diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-01 12:13:12 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-01 12:13:12 +0000 |
commit | d27481e8f3dd252b543f65cb56a98eeb00de855f (patch) | |
tree | 4d4c065f0bbc5c51b61b1d34b2ac1bfdfb3e050b /workhorse/internal/headers/content_headers.go | |
parent | 0f9e3a905651933ea4ca04712ae77ec47d8562e5 (diff) | |
download | gitlab-ce-d27481e8f3dd252b543f65cb56a98eeb00de855f.tar.gz |
Add latest changes from gitlab-org/security/gitlab@15-11-stable-ee
Diffstat (limited to 'workhorse/internal/headers/content_headers.go')
-rw-r--r-- | workhorse/internal/headers/content_headers.go | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/workhorse/internal/headers/content_headers.go b/workhorse/internal/headers/content_headers.go index 854cc8abddd..54c7c1bdd95 100644 --- a/workhorse/internal/headers/content_headers.go +++ b/workhorse/internal/headers/content_headers.go @@ -1,6 +1,7 @@ package headers import ( + "mime" "net/http" "regexp" @@ -13,8 +14,9 @@ var ( imageTypeRegex = regexp.MustCompile(`^image/*`) svgMimeTypeRegex = regexp.MustCompile(`^image/svg\+xml$`) - textTypeRegex = regexp.MustCompile(`^text/*`) - + textTypeRegex = regexp.MustCompile(`^text/*`) + xmlTypeRegex = regexp.MustCompile(`^text/xml`) + xhtmlTypeRegex = regexp.MustCompile(`^text/html`) videoTypeRegex = regexp.MustCompile(`^video/*`) pdfTypeRegex = regexp.MustCompile(`application\/pdf`) @@ -26,6 +28,8 @@ var ( // Mime types that can't be inlined. Usually subtypes of main types var forbiddenInlineTypes = []*regexp.Regexp{svgMimeTypeRegex} +var htmlRenderingTypes = []*regexp.Regexp{xmlTypeRegex, xhtmlTypeRegex} + // Mime types that can be inlined. We can add global types like "image/" or // specific types like "text/plain". If there is a specific type inside a global // allowed type that can't be inlined we must add it to the forbiddenInlineTypes var. @@ -38,12 +42,28 @@ const ( textPlainContentType = "text/plain; charset=utf-8" attachmentDispositionText = "attachment" inlineDispositionText = "inline" + dummyFilename = "blob" ) func SafeContentHeaders(data []byte, contentDisposition string) (string, string) { - contentType := safeContentType(data) + detectedContentType := detectContentType(data) + + contentType := safeContentType(detectedContentType) contentDisposition = safeContentDisposition(contentType, contentDisposition) + // Some browsers will render XML inline unless a filename directive is provided with a non-xml file extension + // This overrides the filename directive in the case of XML data + for _, element := range htmlRenderingTypes { + if isType(detectedContentType, element) { + disposition, directives, err := mime.ParseMediaType(contentDisposition) + if err == nil { + directives["filename"] = dummyFilename + contentDisposition = mime.FormatMediaType(disposition, directives) + break + } + } + } + // Set attachments to application/octet-stream since browsers can do // a better job distinguishing certain types (for example: ZIP files // vs. Microsoft .docx files). However, browsers may safely render SVGs even @@ -56,15 +76,17 @@ func SafeContentHeaders(data []byte, contentDisposition string) (string, string) return contentType, contentDisposition } -func safeContentType(data []byte) string { +func detectContentType(data []byte) string { // Special case for svg because DetectContentType detects it as text if svg.Is(data) { return svgContentType } // Override any existing Content-Type header from other ResponseWriters - contentType := http.DetectContentType(data) + return http.DetectContentType(data) +} +func safeContentType(contentType string) string { // http.DetectContentType does not support JavaScript and would only // return text/plain. But for cautionary measures, just in case they start supporting // it down the road and start returning application/javascript, we want to handle it now |