Repository navigation
USWDS - Bug: file upload component is incompatible with a typical content security policy (CSP) #5990
Copy link
Copy link
Closed
Labels
Added during SprintHistorical record of work added during a sprint. Not required for current triage.Historical record of work added during a sprint. Not required for current triage.
Milestone
Description
Describe the bug
The file input component uses an onerror inline Javascript event handler which is incompatible with a typical Content Security Policy (CSP). This page explains in more detail that inline javascript is not allowed with a nonce- or hash-based approach to strict CSP.
Steps to reproduce the bug
- Create a page with a file input component
- Set a content security policy on the page, e.g. "script-src 'nonce-st+WdPSI/W6r3q3iFeG/hQ==' 'strict-dynamic' https:" (in production the nonce value changes on each request). You can do this by setting the
Content-Security-PolicyHTTP header, or adding an HTML meta element<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-st+WdPSI/W6r3q3iFeG/hQ==' 'strict-dynamic' https:" /> - On your local machine, create an empty text file and rename it to *.jpg
- Open the page and upload the file to the file input component
- Observe that the file preview is a broken image and the browser console shows this error: `Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'nonce-st+WdPSI/W6r3q3iFeG/hQ==' 'strict-dynamic' https:".
Expected Behavior
The file preview image is a generic document icon rather than a broken image, and there are no browser security errors.
Related code
The onerror inline event handler is used several times in this section:
uswds/packages/usa-file-input/src/index.js
Lines 394 to 427 in 369cf3f
| reader.onloadend = function createFilePreview() { | |
| const previewImage = document.getElementById(imageId); | |
| if (fileName.indexOf(".pdf") > 0) { | |
| previewImage.setAttribute( | |
| "onerror", | |
| `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${PDF_PREVIEW_CLASS}")`, | |
| ); | |
| } else if ( | |
| fileName.indexOf(".doc") > 0 || | |
| fileName.indexOf(".pages") > 0 | |
| ) { | |
| previewImage.setAttribute( | |
| "onerror", | |
| `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${WORD_PREVIEW_CLASS}")`, | |
| ); | |
| } else if ( | |
| fileName.indexOf(".xls") > 0 || | |
| fileName.indexOf(".numbers") > 0 | |
| ) { | |
| previewImage.setAttribute( | |
| "onerror", | |
| `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${EXCEL_PREVIEW_CLASS}")`, | |
| ); | |
| } else if (fileName.indexOf(".mov") > 0 || fileName.indexOf(".mp4") > 0) { | |
| previewImage.setAttribute( | |
| "onerror", | |
| `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${VIDEO_PREVIEW_CLASS}")`, | |
| ); | |
| } else { | |
| previewImage.setAttribute( | |
| "onerror", | |
| `this.onerror=null;this.src="${SPACER_GIF}"; this.classList.add("${GENERIC_PREVIEW_CLASS}")`, | |
| ); | |
| } |
To meet CSP requirements, these event handlers should be added via addEventListener on the image element rather than the onerror attribute.
Screenshots
System setup
- USWDS version: 3.6.0
- Device: Macbook
- Operating system: Mac OS 14.5
- Browser and version: Chrome 126.0.6478.184 (arm64)
Additional context
No response
Code of Conduct
- I agree to follow this project's Code of Conduct.
- I checked the current issues for duplicate bug reports.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Added during SprintHistorical record of work added during a sprint. Not required for current triage.Historical record of work added during a sprint. Not required for current triage.
Type
Projects
- StatusShow more project fieldsDone



Activity
mejiaj commentedon Aug 27, 2024
Thanks for reporting this and creating the PR. I've added this issue to our current sprint for confirmation and scheduling the work for review.
7 remaining items
jeffpw-goog commentedon Aug 29, 2024
@mahoneycm I'm happy to help with any issues you see; feel free to DM me on the GSA slack. I'm not sure exactly what you're seeing vs expecting, but if you add the CSP header then all script tags have to have a 'nonce="st+WdPSI/W6r3q3iFeG/hQ=="' attribute in order to load. Here is the branch I used to test on uswds-sandbox: uswds/uswds-sandbox@main...jeffpw-goog:uswds-sandbox:csp-test.
mahoneycm commentedon Aug 30, 2024
@jeffpw-goog Thank you for the demo repo! This helps streamline testing the bug.
I believe my issue surrounded the default way my demo repo was importing the USWDS JS. We'll schedule and test #5997 and reach out if we have any change requests! Thanks again for your engagement on this issue
jeffpw-goog commentedon Sep 26, 2024
Hi @mahoneycm just checking if there's anything else I can do to help get this completed! I'll be rolling off our project and would love to see it wrapped up.
mahoneycm commentedon Oct 7, 2024
Thanks for the bump @jeffpw-goog ! Just got back from some time off and I've updated the issue meta data and added it to our next sprint to review!
mahoneycm commentedon Oct 24, 2024
@jeffpw-goog while we wait for additional peer review, would you be able to submit a changelog for this item? You can leave the date as
NNNN-NN-NNand version number asN.N.N.. You can find additional information in the USWDS site changelog readmeIf you're able to create a PR for the changelog, please add a link to it i the PR description here.
If you're unable to, just let us know!
Thanks Jeff
jeffpw-goog commentedon Oct 25, 2024
@mahoneycm I created a pull request for the changelog as requested: uswds/uswds-site#2912 and added a link under "Related pull requests" in #5997 - let me know if I did anything wrong!