diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index c67b56ad017..e8839087ab7 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -9,6 +9,7 @@ import ( "net/url" "os" gopath "path" + "regexp" "runtime/debug" "strings" "time" @@ -155,6 +156,18 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request ipnsHostname = true } + // Service Worker registration request + if r.Header.Get("Service-Worker") == "script" { + // Disallow Service Worker registration on namespace roots + // https://github.com/ipfs/go-ipfs/issues/4025 + matched, _ := regexp.MatchString(`^/ip[fn]s/[^/]+$`, r.URL.Path) + if matched { + err := fmt.Errorf("registration is not allowed for this scope") + webError(w, "navigator.serviceWorker", err, http.StatusBadRequest) + return + } + } + parsedPath := ipath.New(urlPath) if err := parsedPath.IsValid(); err != nil { webError(w, "invalid ipfs path", err, http.StatusBadRequest) diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 26726f1d5e2..68172cb5655 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -36,6 +36,13 @@ test_expect_success "GET IPFS path with explicit filename succeeds with proper h grep -F \"Content-Disposition: inline; filename*=UTF-8''test%D1%82%D0%B5%D1%81%D1%82\" actual_headers " +# https://github.com/ipfs/go-ipfs/issues/4025#issuecomment-342250616 +test_expect_success "GET for Service Worker registration outside of an IPFS content root errors" " + curl -H 'Service-Worker: script' -svX GET 'http://127.0.0.1:$port/ipfs/$HASH?filename=sw.js' > curl_sw_out 2>&1 && + grep 'HTTP/1.1 400 Bad Request' curl_sw_out && + grep 'navigator.serviceWorker: registration is not allowed for this scope' curl_sw_out +" + test_expect_success "GET IPFS path output looks good" ' test_cmp expected actual && rm actual