Skip to content
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: Selective CSP header stripping from HTTPResponse #26483

Conversation

pgoforth
Copy link
Contributor

@pgoforth pgoforth commented Apr 11, 2023

User facing changelog

  • Cypress now allows selective stripping of Content-Security-Policy and Content-Security-Policy-Report-Only header directives via the stripCspDirectives config option.

Additional details

  • add generated nonce to inline script injection
  • append generated nonce policy value to each CSP header script-src-elem, script-src, and default-src directive if provided in original response
  • remove mandatory content-security-policy and content-security-policy-report-only header stripping
  • selectively strip problematic CSP directive frame-ancestors because it prevents Cypress from loading target into iframe
  • allows for proviiding CSP directives to strip in the parseCspHeaders method
  • add config option stripCspDirectives that permits selective stripping of individual CSP directives
  • default value for the stripCspDirectives config option maintains existing CSP header stripping

Steps to test

  1. Create a local HTTP server that responds to a request with CSP headers defined
  2. Run a Cypress test that sends a request to the local server, and tests the response header, similar to the following:
const route = 'http://localhost:8080';
cy.request(route).as('route');
cy.get('@route').should(response => {
    expect(response).to.have.property('headers');
    expect(response.headers).to.have.property('content-security-policy');
    expect(response.headers['content-security-policy']).to.match(
        /script-src 'nonce-[^-A-Za-z0-9+/=]|=[^=]|={3,}'/
    );
});
cy.visit(route);

How has the user experience changed?

This change does not affect UI/UX

PR Tasks

@pgoforth
Copy link
Contributor Author

pgoforth commented Apr 11, 2023

I'd like to use this time while the PR is in draft to discuss potentially exposing a configuration option allowing the selective stripping of certain CSP directives, with the goal being to default strip to ALL directives (which maintains parity with current version of Cypress)

The only reason to consider this is to make this feature opt-in, with an eye to changing the default in a future release. I would most definitely need some guidance as to how to best implement any global config setting, but in the end, we may not even want to expose a config property at all. I'll leave it up for discussion.

EDIT
I decided it's in the best interest of all Cypress users to create a config flag called stripCspDirectives: boolean | string | string[] and default it to true

stripCspDirectives: true Would remove the CSP headers entirely and maintain parity with old versions of Cypress.

stripCspDirectives: false would strip ONLY functionality breaking directives...like frame-ancestors

stripCspDirectives: '<directive-name>' would strip ONLY the specific directive defined, potentially including functionality breaking directives...like frame-ancestors

stripCspDirectives: ['<directive-name>', '<directive-name>', ...] would strip ONLY the specific directives defined in the array, potentially including functionality breaking directives...like frame-ancestors

@pgoforth pgoforth force-pushed the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch 6 times, most recently from d3e70e6 to 2706a5e Compare April 14, 2023 21:18
@pgoforth pgoforth force-pushed the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch 3 times, most recently from 4a5f223 to ee0269b Compare April 14, 2023 21:41
@pgoforth pgoforth marked this pull request as ready for review April 14, 2023 21:43
@cypress
Copy link

cypress bot commented Apr 14, 2023

25 flaky tests on run #45566 ↗︎

0 27265 1307 0 Flakiness 25

Details:

feat: Selective CSP header directive stripping from HTTPResponse
Project: cypress Commit: ee0269baaa
Status: Passed Duration: 19:45 💡
Started: Apr 14, 2023 9:53 PM Ended: Apr 14, 2023 10:12 PM
Flakiness  e2e/origin/navigation.cy.ts • 1 flaky test • 5x-driver-electron

View Output Video

Test Artifacts
delayed navigation > errors > redirects to an unexpected cross-origin Output Video
Flakiness  e2e/origin/user_agent_override.cy.ts • 1 flaky test • 5x-driver-electron

View Output Video

Test Artifacts
user agent override > persists modified user agent after cy.go Output Video
Flakiness  cypress/cypress.cy.js • 3 flaky tests • 5x-driver-electron

View Output Video

Test Artifacts
... > correctly returns currentRetry Output Video
... > correctly returns currentRetry Output Video
... > correctly returns currentRetry Output Video
Flakiness  commands/net_stubbing.cy.ts • 1 flaky test • 5x-driver-firefox

View Output Video

Test Artifacts
network stubbing > intercepting request > can delay and throttle a StaticResponse Output
Flakiness  project-setup.cy.ts • 1 flaky test • launchpad-e2e

View Output Video

Test Artifacts
Launchpad: Setup Project > Command for package managers > works with Yarn 3 Plug n Play Output Screenshots Video

The first 5 flaky specs are shown, see all 15 specs in Cypress Cloud.

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings.

@pgoforth pgoforth force-pushed the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch 4 times, most recently from ff189fc to 6d5cf91 Compare April 17, 2023 22:04
@pgoforth
Copy link
Contributor Author

pgoforth commented Apr 18, 2023

Implementation for the config parameter is blocked by #21151. It seems that the server restart is either:

  1. Not happening
  2. Not getting the config updates

I would imagine that it's the later.

EDIT
Seems the restart never happens, which would certainly be the reason for #21151 because the config in the server context is static

@mjhenkes mjhenkes assigned mschile and unassigned mjhenkes Apr 27, 2023
@pgoforth pgoforth force-pushed the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch from 6d5cf91 to 255fc11 Compare April 28, 2023 14:30
@pgoforth pgoforth force-pushed the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch from 255fc11 to 81164af Compare May 5, 2023 21:55
@pgoforth
Copy link
Contributor Author

pgoforth commented May 5, 2023

Everything here works when you set the stripCspDirectives attribute in you cypres.config.js file...you just cannot set is on a per spec/run basis using Cy.config. This is the same fate as the blockHosts parameter in #21151.

This PR stands on it's own, and hopefully (since the parameter is setup the same way as blockHosts, when that issue is resolved, this one should be too.

@mschile
Copy link
Contributor

mschile commented May 5, 2023

Hi @pgoforth 👋, thanks for this contribution! I'm planning on bringing it up next week with the team so we can discuss it.

@mschile mschile assigned chrisbreiding and unassigned mschile May 9, 2023
cli/types/cypress.d.ts Outdated Show resolved Hide resolved
cli/CHANGELOG.md Outdated Show resolved Hide resolved
packages/config/src/validation.ts Outdated Show resolved Hide resolved
@pgoforth
Copy link
Contributor Author

pgoforth commented Jun 5, 2023

@AtofStryker Looks like the snapshots for the new system tests I wrote need updating, and I had to update a unit test. I do not know how to run the system tests and update the snapshots. I'm rebasing off develop, resolving the conflict, and pushing up the unit test fix. Hopefully you can get the snapshots updated and passing.

@pgoforth pgoforth force-pushed the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch from f473888 to 1b5b4fb Compare June 5, 2023 22:33
- Add additional system tests
- Update snapshots and unit test
@pgoforth pgoforth force-pushed the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch from 1b5b4fb to e1142ec Compare June 5, 2023 22:33
@AtofStryker
Copy link
Contributor

@pgoforth taking a look and should have it updated soon

* specified will remain in the response headers.
*
* Please see the documentation for more information.
* @see https://on.cypress.io/configuration#experimentalCspAllowList
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mschile since this isn't making it into today's release you may have to handle it for the next release

@AtofStryker
Copy link
Contributor

@emilyrohrbough I think this is ready for another look. I needed to tweak the system tests a bit but I think they provide ample coverage. We also added sandbox and navigate-to to the always strip directive since sandbox seems to apply to all iframes, which breaks Cypress, and navigate-to is not implemented in any browser yet and could very like cause issues with app navigation since in some cases we interact with the document directly.

@AtofStryker AtofStryker assigned mschile and unassigned AtofStryker Jun 6, 2023
@AtofStryker
Copy link
Contributor

@pgoforth we are working on getting a few additional reviewers for this PR on Monday. TLDR there is a test that is failing in CI on your branch, but we believe it is due to flake since the same commits on a different branch owned by cypress ICs seems to work fine. This should be going into develop next week barring anything that might be problematic that is caught in review.

@pgoforth
Copy link
Contributor Author

pgoforth commented Jun 9, 2023

@AtofStryker That all sounds great. I'm OOO next week, but will have my machine with me while I'm traveling. Let me know if there's anything I can assist with and will do my best to help out.

@mjhenkes mjhenkes merged commit 71c5b86 into cypress-io:develop Jun 14, 2023
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Jun 20, 2023

Released in 12.15.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v12.15.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Jun 20, 2023
@pgoforth pgoforth deleted the issue-1030/pgoforth/load-site-witout-csp-header-stripping branch June 20, 2023 20:42
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Figure out how to load site with Content-Security-Policy without stripping header
6 participants