From e1142ec1dd1fb54d07a471e23f0fbde8c23a37e4 Mon Sep 17 00:00:00 2001
From: Preston Goforth
Date: Mon, 5 Jun 2023 17:47:39 -0400
Subject: [PATCH] chore: Move 'sandbox' and 'navigate-to' into
`unsupportedCSPDirectives` - Add additional system tests - Update snapshots
and unit test
---
cli/types/cypress.d.ts | 2 +-
packages/config/src/options.ts | 2 +-
packages/proxy/lib/http/util/csp-header.ts | 10 +++++++++-
packages/server/test/unit/config_spec.js | 4 ++--
.../with_allow_list_custom_or_true.cy.ts | 19 +++++++++++++++++++
5 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts
index 8f0a0c6f9a01..b41954e27087 100644
--- a/cli/types/cypress.d.ts
+++ b/cli/types/cypress.d.ts
@@ -2672,7 +2672,7 @@ declare namespace Cypress {
force: boolean
}
- type experimentalCspAllowedDirectives = 'default-src' | 'child-src' | 'frame-src' | 'script-src' | 'script-src-elem' | 'sandbox' | 'form-action' | 'navigate-to'
+ type experimentalCspAllowedDirectives = 'default-src' | 'child-src' | 'frame-src' | 'script-src' | 'script-src-elem' | 'form-action'
type scrollBehaviorOptions = false | 'center' | 'top' | 'bottom' | 'nearest'
diff --git a/packages/config/src/options.ts b/packages/config/src/options.ts
index 244c27879696..d708fae20e92 100644
--- a/packages/config/src/options.ts
+++ b/packages/config/src/options.ts
@@ -201,7 +201,7 @@ const driverConfigOptions: Array = [
}, {
name: 'experimentalCspAllowList',
defaultValue: false,
- validation: validate.validateAny(validate.isBoolean, validate.isArrayIncludingAny('script-src-elem', 'script-src', 'default-src', 'sandbox', 'form-action', 'navigate-to', 'child-src', 'frame-src')),
+ validation: validate.validateAny(validate.isBoolean, validate.isArrayIncludingAny('script-src-elem', 'script-src', 'default-src', 'form-action', 'child-src', 'frame-src')),
overrideLevel: 'never',
requireRestartOnChange: 'server',
}, {
diff --git a/packages/proxy/lib/http/util/csp-header.ts b/packages/proxy/lib/http/util/csp-header.ts
index 4a4ec2739106..94bc14dc1a27 100644
--- a/packages/proxy/lib/http/util/csp-header.ts
+++ b/packages/proxy/lib/http/util/csp-header.ts
@@ -8,7 +8,7 @@ export const nonceDirectives = ['script-src-elem', 'script-src', 'default-src']
export const problematicCspDirectives = [
...nonceDirectives,
- 'child-src', 'frame-src', 'sandbox', 'form-action', 'navigate-to',
+ 'child-src', 'frame-src', 'form-action',
] as Cypress.experimentalCspAllowedDirectives[]
export const unsupportedCSPDirectives = [
@@ -19,6 +19,14 @@ export const unsupportedCSPDirectives = [
* top-level frame.
*/
'frame-ancestors',
+ /**
+ * The `navigate-to` directive is not yet fully supported, so we are erring on the side of caution
+ */
+ 'navigate-to',
+ /**
+ * The `sandbox` directive seems to affect all iframes on the page, even if the page is a direct child of Cypress
+ */
+ 'sandbox',
/**
* Since Cypress might modify the DOM of the application under test, `trusted-types` would prevent the
* DOM injection from occurring.
diff --git a/packages/server/test/unit/config_spec.js b/packages/server/test/unit/config_spec.js
index 96a23423665f..75f3709b129d 100644
--- a/packages/server/test/unit/config_spec.js
+++ b/packages/server/test/unit/config_spec.js
@@ -573,7 +573,7 @@ describe('lib/config', () => {
})
context('experimentalCspAllowList', () => {
- const experimentalCspAllowedDirectives = JSON.stringify(['script-src-elem', 'script-src', 'default-src', 'sandbox', 'form-action', 'navigate-to', 'child-src', 'frame-src']).split(',').join(', ')
+ const experimentalCspAllowedDirectives = JSON.stringify(['script-src-elem', 'script-src', 'default-src', 'form-action', 'child-src', 'frame-src']).split(',').join(', ')
it('passes if false', function () {
this.setup({ experimentalCspAllowList: false })
@@ -600,7 +600,7 @@ describe('lib/config', () => {
})
it('passes if subset of Cypress.experimentalCspAllowedDirectives[]', function () {
- this.setup({ experimentalCspAllowList: ['default-src', 'sandbox'] })
+ this.setup({ experimentalCspAllowList: ['default-src', 'form-action'] })
return this.expectValidationPasses()
})
diff --git a/system-tests/projects/e2e/cypress/e2e/experimental_csp_allow_list_spec/with_allow_list_custom_or_true.cy.ts b/system-tests/projects/e2e/cypress/e2e/experimental_csp_allow_list_spec/with_allow_list_custom_or_true.cy.ts
index 02deac238782..b55415c514e3 100644
--- a/system-tests/projects/e2e/cypress/e2e/experimental_csp_allow_list_spec/with_allow_list_custom_or_true.cy.ts
+++ b/system-tests/projects/e2e/cypress/e2e/experimental_csp_allow_list_spec/with_allow_list_custom_or_true.cy.ts
@@ -39,6 +39,25 @@ describe('experimentalCspAllowList is custom or true', () => {
cy.get('h1').contains('CSP Script Test Modified').should('be.visible')
})
+
+ it('sandbox is always stripped', () => {
+ // Since sandbox is inclusive, all other sandbox actions would be restricted except for `allow-downloads`
+ visitUrl.searchParams.append('csp', `sandbox 'allow-downloads'`)
+ cy.visit(visitUrl.toString())
+
+ // expect the form to post and navigate to a new page, meaning the sandbox directive was stripped
+ cy.get('#submit').click()
+ cy.contains('Cannot POST /').should('exist')
+ })
+
+ it('navigate-to is always stripped', () => {
+ visitUrl.searchParams.append('csp', `navigate-to 'none'`)
+ cy.visit(visitUrl.toString())
+
+ // expect the form to post and navigate to a new page, meaning the navigate-to directive was stripped
+ cy.get('#submit').click()
+ cy.contains('Cannot POST /').should('exist')
+ })
})
describe('allowed', () => {