Whitelist for preview files from the backend (#1651)

This PR adds a whitelist of safe files to download with
`Content-Disposition: inline;` from the backend, all other files will be
force download via `Content-Disposition: attachment;` existing svg files
will still be rendered in a secure way via the html `image` tag.

reference: https://digi.ninja/blog/svg_xss.php

Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
This commit is contained in:
Lenin Alevski
2022-03-02 12:18:43 -08:00
committed by GitHub
parent 20ba19affc
commit 26d5972ab5
3 changed files with 47 additions and 4 deletions

View File

@@ -254,7 +254,7 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
}
// Allow iframes
responseWriter.Header().Set("X-Frame-Options", "SAMEORIGIN")
responseWriter.Header().Set("X-XSS-Protection", "1")
responseWriter.Header().Set("X-XSS-Protection", "1; mode=block")
io.Copy(responseWriter, resp.Body)

View File

@@ -415,18 +415,18 @@ func getDownloadObjectResponse(session *models.Principal, params user_api.Downlo
LogError("Unable to parse range header input %s: %v", params.HTTPRequest.Header.Get("Range"), err)
return
}
contentType := stat.ContentType
rw.Header().Set("X-XSS-Protection", "1; mode=block")
if isPreview {
if isPreview && isSafeToPreview(contentType) {
rw.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", escapedName))
rw.Header().Set("X-Frame-Options", "SAMEORIGIN")
rw.Header().Set("X-XSS-Protection", "1")
} else {
rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", escapedName))
}
rw.Header().Set("Last-Modified", stat.LastModified.UTC().Format(http.TimeFormat))
contentType := stat.ContentType
if isPreview {
// In case content type was uploaded as octet-stream, we double verify content type
if stat.ContentType == "application/octet-stream" {

View File

@@ -144,3 +144,46 @@ func ExpireSessionCookie() http.Cookie {
func SanitizeEncodedPrefix(rawPrefix string) string {
return strings.Replace(rawPrefix, " ", "+", -1)
}
var safeMimeTypes = []string{
"image/jpeg",
"mage/apng",
"image/avif",
"image/webp",
"image/bmp",
"image/x-icon",
"image/gif",
"image/png",
"image/heic",
"image/heif",
"application/pdf",
"text/plain",
"application/json",
"audio/wav",
"audio/mpeg",
"audio/aiff",
"audio/dsd",
"video/mp4",
"video/x-msvideo",
"video/mpeg",
"audio/webm",
"video/webm",
"video/quicktime",
"video/x-flv",
"audio/x-matroska",
"video/x-matroska",
"video/x-ms-wmv",
"application/metastream",
"video/avchd-stream",
"audio/mp4",
"video/mp4",
}
func isSafeToPreview(str string) bool {
for _, v := range safeMimeTypes {
if v == str {
return true
}
}
return false
}