Skip to content

Commit

Permalink
gateway: harden path prefix
Browse files Browse the repository at this point in the history
Only allow paths, so we stay local to this gateway,
and don't get tricked into linking to a different host,
or even redirecting to one.

I can't come up with a concrete attack right off the bat,
but who knows how things are going to change.
Not restricting it would be silly.

License: MIT
Signed-off-by: Lars Gierth <larsg@systemli.org>
  • Loading branch information
Lars Gierth committed Nov 21, 2015
1 parent 93c2309 commit dd7cddc
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
7 changes: 5 additions & 2 deletions core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
// It will be prepended to links in directory listings and the index.html redirect.
prefix := ""
if prefixHdr := r.Header["X-Ipfs-Gateway-Prefix"]; len(prefixHdr) > 0 {
log.Debugf("X-Ipfs-Gateway-Prefix: %s", prefixHdr[0])
prefix = prefixHdr[0]
prfx := prefixHdr[0]
if strings.HasPrefix(prfx, "/") {
log.Debugf("X-Ipfs-Gateway-Prefix: %s", prfx)
prefix = prfx
}
}

// IPNSHostnameOption might have constructed an IPNS path using the Host header.
Expand Down
31 changes: 31 additions & 0 deletions core/corehttp/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,35 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
if !strings.Contains(s, "<a href=\"/prefix/file.txt\">") {
t.Fatalf("expected file in directory listing")
}

// make request to directory listing with illegal prefix
req, err = http.NewRequest("GET", ts.URL, nil)
if err != nil {
t.Fatal(err)
}
req.Host = "example.net"
req.Header.Set("X-Ipfs-Gateway-Prefix", "http://evil.com")

res, err = doWithoutRedirect(req)
if err != nil {
t.Fatal(err)
}

// expect correct backlinks without illegal prefix
body, err = ioutil.ReadAll(res.Body)
if err != nil {
t.Fatalf("error reading response: %s", err)
}
s = string(body)
t.Logf("body: %s\n", string(body))

if !strings.Contains(s, "Index of /") {
t.Fatalf("expected a path in directory listing")
}
if !strings.Contains(s, "<a href=\"/\">") {
t.Fatalf("expected backlink in directory listing")
}
if !strings.Contains(s, "<a href=\"/file.txt\">") {
t.Fatalf("expected file in directory listing")
}
}

0 comments on commit dd7cddc

Please sign in to comment.