1) Eliminate the potential for users to control the uploaded file’s mime-type by setting the file.mimeType in request to be the mime type detected from FileType library
2) If no mime type detected from FileType library, we look at file name extension and map it to a list of accepted mime type to prevent XSS - set the mime-type to plain text for all uploaded files the library is unable to detect except for .csv, .dwf and .dxf files.
csv: text/csv
dwf: application/x-dwf
dxf: application/dxf
others: text/plain
Tests
File types that cannot be detected by file type library
txt:
csv:
dwf:
dxf:
svg (with .txt extension) attack (should be opened with text/plain)
Problem
Fixes VAPT vulnerability
GTA-18-005 WP1: Stored XSS via file upload
More information about the vulnerability can be found here: https://www.notion.so/opengov/20230711-Go-VAPT-Documents-b3e410c4b7634f229de8c9b7af5dbb7d
Closes Stored XSS via file upload
Solution
1) Eliminate the potential for users to control the uploaded file’s mime-type by setting the file.mimeType in request to be the mime type detected from FileType library
2) If no mime type detected from FileType library, we look at file name extension and map it to a list of accepted mime type to prevent XSS - set the mime-type to plain text for all uploaded files the library is unable to detect except for .csv, .dwf and .dxf files.
Tests
File types that cannot be detected by file type library
txt:
csv:
dwf:
dxf:
svg (with .txt extension) attack (should be opened with text/plain)
curl --location 'localhost:3000/api/user/url' \ --header 'Cookie: gogovsg=s%3AOJmJWpvX5i_UcFNVmA8q0Dw4ndire9Ks.lf36B%2FGGhiszvyvgCw%2FncM5vivQhxVoIWOAQ%2FDNKwKs; Cookie_1=value' \ --header 'Content-Type: image/svg+xml' \ --form 'file=@"/Users/thamsimun/Downloads/test-vapt-svg.txt"' \ --form 'shortUrl="test-svg-xss-attack"'
File that can be detected by file type library (check if they have same behaviour as current behaviour in prod/staging)
pdf:
docx:
jpg:
jpeg:
png:
avi:
bmp:
dwg:
gif:
mpeg:
mpg:
ods:
pptx:
rtf:
tif:
tiff:
xlsx:
zip: