Draft: Add content type allowlist and return generic package file with the content type
What does this MR do and why?
Currently, when user uploads a generic package file, the system will store the file in object storage as binary/octet-stream in MinIO and when users try to (for example) get a css file via a html page, because of the wrong content type, the browser will stop the file from being downloaded.
In the previous MR, we found a security concern that if we just return the file with the correct content types, it may lead to XSS attacks. For example, if a user uploads a malicious JavaScript file to the generic package registry and we serve it with content-type: application/javascript, the browser will execute the script when it's loaded (e.g., via <script src="...">), potentially allowing XSS attacks. Currently, serving it as binary/octet-stream prevents the browser from executing it as JavaScript.
After some discussions, we decided to create a allowlist of content types, and only return the specific content-type in header when it's allowed.
We've collected all the possible content types and this MR will start use the defined allowlist and return generic package file with allowed content-type when feature flag packages_generic_package_content_type_allowlist is enabled.
References
Screenshots or screen recordings
N/A
How to set up and validate locally
-
Switch to this branch
552990-return-generic-package-file-with-content-type -
Open another tab and create a new folder
-
Create test css file
body { background-color: #f0f0f0; font-family: Arial, sans-serif; color: #333; } .test-element { background-color: #007bff; color: white; padding: 10px; border-radius: 5px; } -
Upload CSS file to generic package registry
curl --location -v \ --header "PRIVATE-TOKEN: ${TOKEN}" \ --upload-file test_css.css \ "${GITLAB_URL}/api/v4/projects/${PROJECT_ID}/packages/generic/test-generic-package/2.3.3/test_css.css" -
Download css file and check the header
curl -I --header "PRIVATE-TOKEN: ${TOKEN}" \ "${GITLAB_URL}/api/v4/projects/${PROJECT_ID}/packages/generic/test-generic-package/2.3.3/test_css.css" ... Content-Type: application/octet-stream ... -
Enter rails console and enabled the feature flag
Feature.enable(:packages_generic_package_content_type_allowlist) -
Download the css again, the header
Content-Typeshould be proper returnedcurl -I --header "PRIVATE-TOKEN: ${TOKEN}" \ "${GITLAB_URL}/api/v4/projects/${PROJECT_ID}/packages/generic/test-generic-package/2.3.3/test_css.css" ... Content-Type: text/css ...
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #552990