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

Feature: CSP should allow simultaneous Content-Security-Policy-Report-Only and Content-Security-Policy-Report-Only #351

Closed
thernstig opened this issue Jan 18, 2022 · 7 comments

Comments

@thernstig
Copy link
Contributor

thernstig commented Jan 18, 2022

Currently an option exists to allow only reporting of violations:

options.reportOnly is a boolean, defaulting to false. If true, the Content-Security-Policy-Report-Only header will be set instead.

But according to https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#testing_your_policy it should be allowed to include both a Content-Security-Policy and Content-Security-Policy-Report-Only header.

Usage scenario
Let's say you have a current CSP policy, but want to evaluate a new, future policy. This means you want to continue using the one you already enforce, but at the same time evaluate the new one. Read more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only

I think this in turn should remove options.reportOnly in a new major release. Users would instead get full functionality via:

app.use(
  helmet.contentSecurityPolicy({
    policy: {
      directives: {
        "script-src": ["'self'", "example.com"],
      },
    },
    reportPolicy: {
      directives: { // or reportPolicy
        "script-src": ["'self'", "example.com", "lolcat.com"],
      },
    },
  })
);

Unfortunately this means the top-level properties needs to be moved into a policy and reportPolicy property. This is to allow options such as options.useDefaults to be set per header.

@EvanHahn
Copy link
Member

This is an interesting idea and one I'll keep in mind. It's possible that we could add this without a breaking change, which I'll have to think about.

Here's one way you could do this with Helmet today:

app.use(
  helmet.contentSecurityPolicy({
    reportOnly: false,
    directives: {
      /* ... */
    },
  })
);

app.use(
  helmet.contentSecurityPolicy({
    reportOnly: true,
    directives: {
      /* ... */
    },
  })
);

Would something like this work for you?

@thernstig
Copy link
Contributor Author

That is interesting, was not aware that works. That is good info.

From an API standpoint I think the initially proposed solution is the most elegant one. Of course carefully contemplating this before doing anything is good.

EvanHahn added a commit that referenced this issue Apr 1, 2022
@EvanHahn
Copy link
Member

EvanHahn commented Apr 1, 2022

After some consideration, I don't think I'm going to add this to Helmet for three reasons:

  1. I don't want to increase Helmet's surface area if I can help it.
  2. I don't think this is a very common use case. I'm sure you're not the only one to want this, but this isn't a common feature request.
  3. The workaround is, in my opinion, straightforward.

We'd have to document the new feature anyway. Why not just document the workaround instead? I've added a note to the documentation (see 7848f5a) to make this more obvious for people in the future.

I'm going to close this issue because I think it's resolved, but let me know if you disagree.

@EvanHahn EvanHahn closed this as completed Apr 1, 2022
@thernstig
Copy link
Contributor Author

@EvanHahn documentation it makes perfect sense, and I do think the workaround is good as-is. Thanks for a great project.

@amochuko
Copy link

Hi @EvanHahn
I learnt CSP report-uri is deprecated https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri and instead to use report-to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-to

I couldn't find such interface implemented in helmetJS when I wanted using it. So I was thinking if it's wise extending interface ContentSecurityPolicyOptions or better still; please, direct a resolve for me.

Thanks.

@EvanHahn
Copy link
Member

EvanHahn commented Aug 26, 2022

@iamochuko You should be able to use the report-to directive like this:

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      // ...
      "report-to": ["groupname"],
    },
  })
);

Please open a new issue if you run into problems.

@amochuko
Copy link

@EvanHahn I will give it a go once I return to my station. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants