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

CSP guide updates #36157

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open

CSP guide updates #36157

wants to merge 30 commits into from

Conversation

wbamberg
Copy link
Collaborator

@wbamberg wbamberg commented Oct 2, 2024

This is more or less a rewrite of the CSP guide.

The main motivation is to fix #35812, which says we should document strict (nonce or hash based) CSPs and recommend them over allowlist-based CSPs. So this version adds much more material on how to use nonces and hashes, and outlines (and recommends) strict CSP.

Another motivation is to help address the issue raised in https://publications.cispa.saarland/2986/1/roth2020csp.pdf, which says essentially that because using CSPs to control resource loads has such a bad rep, people don't use the other features of it like clickjacking protection, and the docs don't talk about these other features enough. For example:

in conversations with operators, several mentioned
that they relied on external resources for security headers. In
checking those resources, we found that they all list XFO as
the only defense against framing-based attacks, whereas they
advertised CSP as a means to mitigate XSS attacks [4, 5,
13, 38, 49]. Notably, even widely-used sites like securi-
tyheaders.com consider XFO the only viable option for
framing control. Neither this service nor other resources like
MDN [24] indicate that CSP can be used for this purpose.

and

it appears that the com-
plexity for script content restriction gives CSP a bad reputation.
Given that this is not counteracted by widely used resources
pointing out the easy-to-deploy use cases of TLS enforcement
and framing control, we advocate for clear communication of
the individual goals in such resources.

So in this version I have a single section on "Controlling resource loading" but other sections on "Clickjacking protection" and "Upgrading insecure requests". Especially the second of these, although easy to deploy, is quite a subtle use case that wasn't at all well documented anywhere on MDN as far as I could see.

Various other things.

  1. It's very long. We might consider splitting it into separate pages?
  2. For the Testing your policy section, I just copied what was there before. We might look to improve it but it looked OK and tbh I had rather run out of steam by that point.
  3. The old guide had a paragraph near the start about compatibility. I just took that out. I think CSP compat is pretty good except for report-to, for which we discuss compat, and trusted types, which aren't in this guide.
  4. I didn't add anything on trusted type directives. Partly that's because they are currently only supported in Chromium, and partly because this PR was big enough already. It would be a good follow-up to add a new section on this.
  5. The old page had lots of examples of allowlists. I just took them out. We might want to present them, too, alongside strict CSP (but recommend strict CSP).

@github-actions github-actions bot added Content:HTTP HTTP docs size/m [PR only] 51-500 LoC changed labels Oct 2, 2024
Copy link
Contributor

github-actions bot commented Oct 2, 2024

Preview URLs

External URLs (6)

URL: /en-US/docs/Web/HTTP/CSP
Title: Content Security Policy (CSP)

(comment last updated: 2024-10-18 23:07:08)

@wbamberg wbamberg changed the title First commit of new CSP guide CSP guide updates Oct 2, 2024
@github-actions github-actions bot added size/l [PR only] 501-1000 LoC changed and removed size/m [PR only] 51-500 LoC changed labels Oct 3, 2024
@wbamberg wbamberg marked this pull request as ready for review October 4, 2024 01:51
@wbamberg wbamberg requested a review from a team as a code owner October 4, 2024 01:51
@wbamberg wbamberg requested review from hamishwillee and removed request for a team October 4, 2024 01:51

## Threats
- the `default-src` directive is set to `'self'`
Copy link
Collaborator

@hamishwillee hamishwillee Oct 6, 2024

Choose a reason for hiding this comment

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

Is it worth adding a brief explanation here of each directive? Something like

Suggested change
- the `default-src` directive is set to `'self'`
- the `default-src` directive is set to `'self'`, which allows only same-origin resources to be loaded for directives that aren't specified.

One thing I've always found quite powerful is that default-src is a catchall. The implication being that you typically lock down everything, then progressively allow access. You mention it below, but maybe something here too.

Copy link
Collaborator

Choose a reason for hiding this comment

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

PS I understand this is just the first mention, and you want to show the format of the directive string. Feels a little "abstract" even for an overview.

Copy link
Collaborator

Choose a reason for hiding this comment

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

On reflection, perhaps a paragraph after the image stating something like

The first (default-src) directive sets a restriction that will be used to allow only same-origin resources to be loaded for directives that aren't specified. The second explicitly ....

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 1ada7b0, although I didn't really want to. At this point I only really want to explain that, syntactically, there are these things called directives. By explaining what particular directives do I worry that we're trying to explain everything at once, and making it overwhelming.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I slightly prefer it as you have now done it, though certainly arguable. If you really hate it feel free to remove.

```http
Content-Security-Policy: default-src 'self' example.com *.example.com
#### Nonces

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure of the best way to do this, but if Nonces/Hashes are the recommended way to manage script resource then it would be better to have them before location based info. Minimally here we might forward reference the CSP Strict section with a note like

Note: Nonces and hashes are recommended over location based restrictions for script resources. See [CSP strict] below ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think structurally it would be straightforward to move "Nonces" and "Hashes" to be the first H4 headings under "Fetch directives". But I don't want to do this yet, I want confirmation that we really do only want to recommend strict CSP. The "Practical security guides" (https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides) that @chrisdavidmills migrated from mozilla.org does not recommend strict CSP, and I'd like to be sure we have consensus for this change.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree that moving them would be better. Who do we need to talk to for consensus?

W.r.t. the implementation guide, that just says "CSP", so its not a for or against the strict kind.
@chrisdavidmills Just FYI it refers to things like Clickjacking protection using iframes, but does not mention CSP in this context or COEP that provide a more layered defense for this particular problem. Not sure if worth addressing.

Copy link
Collaborator Author

@wbamberg wbamberg Oct 18, 2024

Choose a reason for hiding this comment

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

I agree that moving them would be better.

Fair enough, I've moved them in 8f6af6d. Still have 'none' first though.

Who do we need to talk to for consensus?

I think Chris is in touch with the Mozilla security team.

W.r.t. the implementation guide, that just says "CSP", so its not a for or against the strict kind.

It is though, the table row on CSP in https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides#content_security_fundamentals links to https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/CSP#steps_for_implementing_csp, which describes an allowlist-based approach.

@wbamberg
Copy link
Collaborator Author

@hamishwillee , I have made some changes, argued with some others, and think this is ready for another look. Thank you!

Note that this example doesn't specify a {{CSP("script-src")}}, so the {{CSP("default-src")}} directive will be used for JavaScript sources as a fallback.
The browser will upgrade the first link to HTTPS, but not the second, as it is navigating to a different origin.

This directive is not a substitute for the {{httpheader("Strict-Transport-Security")}} header (also known as HSTS), because it does not upgrade external links to a site. Sites should include this directive and the `Strict-Transport-Security` header.

## Testing your policy

Copy link
Collaborator

Choose a reason for hiding this comment

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

Below it says

The policy is not enforced, but any violations are reported to a provided URI

Maybe

The policy is not enforced, but any violations are sent to the reporting endpoint specified in the policy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

-> 079e4f0


### Strict CSP

To control script loading as a mitigation against XSS, recommended practice is to use nonce- or hash- based fetch directives. This is called a _strict CSP_. This type of CSP has two main advantages over a location-based CSP (usually called an _allowlist CSP_):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Link nonce- and hash- to their headings above?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

-> 079e4f0


```http
Content-Security-Policy: default-src 'self'
Content-Security-Policy:
script-src 'nonce-{RANDOM}';
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. What about stylesheets?
  2. Should we show a list of nonces here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  1. What about stylesheets?

Good question. I just copies this from the web.dev and OWASP articles. One thing that bothers me in general about strict CSP is that it doesn't say anything about controlling other resource types, only JS. @aaronshim , do you know what we should put here?

  1. Should we show a list of nonces here?

No, because you use the same nonce in every script - it only has to be different for each response.

Copy link
Collaborator

Choose a reason for hiding this comment

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

nonce in every script - it only has to be different for each response.

I'm a numpty - does that need to be spelled out, or is it already?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's indeed not obvious, which is why I did spell it out in an example in https://pr36157.content.dev.mdn.mozit.cloud/en-US/docs/Web/HTTP/CSP#nonces :

Screen Shot 2024-10-18 at 7 39 04 PM

@hamishwillee
Copy link
Collaborator

I've been through it again. REsolved the issues that I think have been addressed.

Really like the new structure for the XSS and resource loading - meets the goals of

  • explaining XSS and how CSP helps
  • will work well if this doc is split.

There are a few inline suggestions, but this is basically good to go from my perspective.

wbamberg and others added 7 commits October 18, 2024 13:55
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content:HTTP HTTP docs size/l [PR only] 501-1000 LoC changed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Document "strict CSP" and recommend it over allowlists
3 participants