Commit 531110f9 authored by Jérome Perrin's avatar Jérome Perrin

fixup! NXD xblob: don't let net/http sniff content type

support rendering svg as images, while still applying a CSP and forcing
download to prevent executing javascript they may contain
parent 82b9d05a
......@@ -11,10 +11,12 @@ import (
"fmt"
"io"
"log"
"mime"
"net/http"
"net/url"
"os"
"os/exec"
"path"
"regexp"
"strings"
"syscall"
......@@ -179,7 +181,6 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string, r *http.Re
}
// Blob found - start writing response
w.Header().Set("Content-Disposition", "inline")
w.Header().Set("Content-Transfer-Encoding", "binary")
w.Header().Set("Content-Length", fmt.Sprintf("%d", size))
w.Header().Set("X-Content-Type-Options", "nosniff")
......@@ -204,12 +205,22 @@ func emitBlob(w http.ResponseWriter, repopath string, refpath string, r *http.Re
// accessed from the /blob/ view.
// See https://gitlab.com/gitlab-org/gitlab-foss/-/blob/77c7b561/app/helpers/blob_helper.rb#L138-144
contentType := http.DetectContentType(buffer)
if strings.HasPrefix(contentType, "text/") {
if mime.TypeByExtension(path.Ext(refpath)) == "image/svg+xml" {
// Serve SVG with a content securtiy policy to prevent execution of inline javascript
// note that the detection is a bit more complex
// https://github.com/golang/go/issues/15888#issuecomment-222457018
w.Header().Set("Content-Type", "image/svg+xml; charset=utf-8")
w.Header().Set("Content-Disposition", "attachment")
w.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox")
} else if strings.HasPrefix(contentType, "text/") {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Header().Set("Content-Disposition", "inline")
} else if strings.HasPrefix(contentType, "image/") {
w.Header().Set("Content-Type", contentType)
w.Header().Set("Content-Disposition", "inline")
} else {
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", "attachment")
}
w.WriteHeader(http.StatusOK) // Don't bother with HTTP 500 from this point on, just return
w.Write(buffer)
......
......@@ -707,9 +707,10 @@ func TestBlobDownload(t *testing.T) {
dl.ExpectHeader("/5f923865/files/js/application.js", "content-type", "text/plain; charset=utf-8")
dl.ExpectHeader("/5f923865/files/images/logo-white.png", "content-type", "image/png")
dl.ExpectHeader("/5f923865/files/images/6049019_460s.jpg", "content-type", "image/jpeg")
dl.ExpectHeader("/5f923865/files/images/wm.svg", "content-type", "text/plain; charset=utf-8")
dl.ExpectHeader("/5f923865/files/images/wm.svg", "content-type", "image/svg+xml; charset=utf-8")
dl.ExpectHeader("/5f923865/files/images/wm.svg", "content-disposition", "attachment")
dl.ExpectHeader("/5f923865/files/images/wm.svg", "content-security-policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox")
dl.ExpectHeader("/5f923865/Gemfile.zip", "content-type", "application/octet-stream")
dl.ExpectHeader("/5f923865/files/images/wm.svg", "content-type", "text/plain; charset=utf-8")
dl.ExpectHeader("/5f923865/VERSION", "content-type", "text/plain; charset=utf-8")
// empty file
dl.ExpectHeader("/5f923865/files/flat/path/correct/content.txt", "content-type", "text/plain; charset=utf-8")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment