-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Do not strip CSP headers from HTTPResponse #24760
feat: Do not strip CSP headers from HTTPResponse #24760
Conversation
Thanks for taking the time to open a PR!
|
I decided to try my hand at remedying the CSP header issue reported by @bahmutov here and implement the suggestion from @flotwig here. I've been having issues building Cypress from source, so I've been unable to run a build and test these changes locally. Any help in this regard would be appreciated. |
Nice, thanks for taking this on.
@pgoforth What's the error you're encountering? |
Error that I see is:
As an aside, I am using yarn
|
@pgoforth I see some commits being pushed up - are you unblocked? I tried to reproduce the "import" issue, but was unable to on Linux. My next step was to try reproducing the issue you were hitting on a Mac. |
@flotwig I have not pushed any updates. I have been rebasing in the hopes that I would get unblocked by other work going into |
@pgoforth Ok, I just tried to We do use Yarn Classic and not Yarn v3. Did you try a fresh clone/ If you still are having trouble after building from a clean clone, please share the full logs, I can take a look. |
@flotwig Good thought. I tried a fresh clone and was able to get everything running. I am unblocked, and am going to run my changes through local manual testing. |
@flotwig and perhaps @mjhenkes
Apparently Edit: For reference on the issue: Edit2: |
@pgoforth Been thinking about this and ultimately I think that this is too dangerous. We want apps running in Cypress to run as closely as possible to how they'd run in a web browser. If we added |
You can serve the cypress domain snippet via a script and not inline. Thus you could use the original csp plus insert a nonce for just the single added scriptSent from my iPhoneOn Dec 7, 2022, at 17:07, Zach Bloomquist ***@***.***> wrote:
Adding unsafe-eval was 100% successful. Cypress is now allowing the CSP headers through, running tests successfully. This might be a nice compromise for the ability to test every other CSP header. Thoughts?
@pgoforth Been thinking about this and ultimately I think that this is too dangerous. We want apps running in Cypress to run as closely as possible to how they'd run in a web browser. If we added unsafe-eval to CSPs, users could push code changes that use eval, all their tests would pass, and then it would completely break in production. What do you think? Is there another way?
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@bahmutov Are you talking about this line of code? The only items necessitating
@flotwig Edit: Edit2: cy.on('uncaught:exception', err => {
expect(err.message).to.include('unsafe-eval');
expect(err.stack).to.include('/injection/main.js');
return false;
}); I just see many other instances where code is injected, triggering |
@flotwig and @bahmutov |
Test summaryRun details
View run in Cypress Dashboard ➡️ Flakiness
This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard |
- add generated `nonce` to inline script injection - append generated `nonce` value to each CSP header `script-src` directive - add `unsafe-eval` to CSP for test runner compatibility - remove `content-security-policy` and `content-security-policy-report-only` header stripping run ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pgoforth Sorry it took me so long to get to reviewing this again. I reviewed your changes and they looked good, really nice job on this. I pushed up a small style fix and an e2e test. Once we get another review on this it can merge.
if (incomingCSPHeaders.length) { | ||
// In order to allow the injected script to run on sites with a CSP header | ||
// we must add a generated `nonce` into the response headers | ||
const nonce = crypto.randomBytes(16).toString('base64') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason I always thought that this was a hash of the script's source, this is way simpler than I thought.
Once this lands and is released it would be really cool to intercept and tear CSP violation reporting Sent from my iPhoneOn Jan 11, 2023, at 10:59, Zach Bloomquist ***@***.***> wrote:
@flotwig approved this pull request.
@pgoforth Sorry it took me so long to get to reviewing this again. I reviewed your changes and they looked good, really nice job on this. I pushed up a small style fix and an e2e test. Once we get another review on this it can merge.
In packages/proxy/lib/http/response-middleware.ts:
@@ -311,6 +313,36 @@ const SetInjectionLevel: ResponseMiddleware = function () {
// We set the header here only for proxied requests that have scripts injected that set the domain.
// Other proxied requests are ignored.
this.res.setHeader('Origin-Agent-Cluster', '?0')
+
+ // Only patch the headers that are being supplied by the response
+ const incomingCSPHeaders = ['content-security-policy', 'content-security-policy-report-only']
+ .filter((headerName) => hasCspHeader(this.incomingRes.headers, headerName))
+
+ if (incomingCSPHeaders.length) {
+ // In order to allow the injected script to run on sites with a CSP header
+ // we must add a generated `nonce` into the response headers
+ const nonce = crypto.randomBytes(16).toString('base64')
For some reason I always thought that this was a hash of the script's source, this is way simpler than I thought.
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@bahmutov timely request :) check out 12.2.0, we added support for So you can do this for example to catch all CSP reports: cy.intercept({ resourceType: 'cspviolationreport' }).as('cspViolationReport') |
@pgoforth Thank you for the contribution, again, great work. This will come out with the next release of Cypress at the beginning of next week. |
Co-authored-by: Zach Bloomquist <[email protected]> Closes #1030
This reverts commit 0472bb9.
* develop: (45 commits) fix: re-enable CYPRESS_INTERNAL_VITE_DEV development (#25364) fix: add skip domain injection description (#25463) fix: revert CSP header and script-src addition (#25445) chore: Update v8 snapshot cache (#25401) feat: Do not strip CSP headers from HTTPResponse (#24760) fix: keep spaces in formatted output in test runner (#24687) fix: Restrict dependency versions to known supported ranges (#25380) chore: Update v8 snapshot cache (#25370) feat: experimental skip domain injection (#25307) chore: support vite v4 for component testing (#25365) feat: Use JSX/TSX in generated spec filenames (#25318) docs(angular): Properties that are spied upon have to be defined within `componentProperties` instead of on root level. (#25359) chore: remove lint-changed from scripts/docs (#25308) chore: bump to 12.3.0 [skip ci] (#25355) fix: make NODE_ENV "production" for prod builds of launchpad (#25320) fix: .contains() should only return one element at all times (#25250) feat: add currentRetry to Cypress API (#25297) chore: release @cypress/webpack-dev-server-v3.2.2 chore: release create-cypress-tests-v2.0.1 fix: change wording for spec creation (#25271) ...
User facing changelog
Content-Security-Policy
andContent-Security-Policy-Report-Only
headers from requests.Additional details
nonce
to inline script injectionnonce
policy value to each CSP headerscript-src
directivecontent-security-policy
andcontent-security-policy-report-only
header strippingSteps to test
// TODO
How has the user experience changed?
This change does not affect UI/UX
PR Tasks
cypress-documentation
?type definitions
?