Skip to content

Figure out how to load site with Content-Security-Policy without stripping header #1030

@bahmutov

Description

@bahmutov

Feature proposal

Currently we strip "content-security-policy" when loading documents.

  • allow rewriting this header in a plugin to only strip what is preventing Cypress from iframing the site

screen shot 2017-12-06 at 8 43 01 pm

By passing through CSP, and possibly tweaking it, we should be able to add security testing to Cypress.

  • is my CSP setup correctly?
  • are my violations reported?
  • can I load code / style / object from given domain or will it throw an error?

Observation

  • if we run content security policy with report-only mode, everything is working and no problems are reported when running the test itself (and any inline scripts are executed, but reported)

using helmet to generate CSP, we can do nothing and just run in report mode.

// basically do not allow inline scripts
app.use(
  helmet.contentSecurityPolicy({
    directives: {
      scriptSrc: ["'self'"],
      reportUri: '/report-violation'
    },
    reportOnly: true
  })
)

In the following page we catch two errors:

<!DOCTYPE html>
<html lang="en">

<head>
  <title></title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
  <p>a few scripts from files index.0.js etc</p>
  <script src="index.0.js"></script>
  <script src="index.1.js"></script>
  <script src="index.2.js"></script>
  <p>an inline script with alert below</p>
  <script>alert('abc')</script>
</body>

</html>
  1. the Cypress injection code <head> <script type='text/javascript'> document.domain = 'localhost'; var Cypress = window.Cypress ...
  2. inline alert call

The server receives the following calls from the browser

Example app listening on port 3000!
CSP Violation:  { 'csp-report': 
   { 'document-uri': 'http://localhost:3000/',
     referrer: 'http://localhost:3000/__/',
     'violated-directive': 'script-src \'self\'',
     'effective-directive': 'script-src',
     'original-policy': 'script-src \'self\'; report-uri /report-violation',
     'blocked-uri': 'inline',
     'line-number': 4,
     'status-code': 200 } }
CSP Violation:  { 'csp-report': 
   { 'document-uri': 'http://localhost:3000/',
     referrer: 'http://localhost:3000/__/',
     'violated-directive': 'script-src \'self\'',
     'effective-directive': 'script-src',
     'original-policy': 'script-src \'self\'; report-uri /report-violation',
     'blocked-uri': 'inline',
     'line-number': 16,
     'status-code': 200 } }

Which leads me to conclude that we should inject our Cypress top level script from external url and not inline (where it might conflict)

Metadata

Metadata

Assignees

No one assigned

    Labels

    stage: needs reviewThe PR code is done & tested, needs reviewtype: featureNew feature that does not currently exist

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions