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

Generalize CSP headers #2248

Merged
merged 2 commits into from
Feb 5, 2024
Merged

Generalize CSP headers #2248

merged 2 commits into from
Feb 5, 2024

Conversation

nmattia
Copy link
Collaborator

@nmattia nmattia commented Feb 1, 2024

This updates the way we create the CSP headers (and in particular, the script-src clause).

Before this, and due to a (now resolved) bug in Firefox, we could not specify integrity= attributes for whitelisting scripts in HTML. Instead we implemented a work around where we injected a new inline script (with known hash) which in turn loaded the actual JS script.

This was unconventional, somewhat unsafe (because it didn't actually include the script's hash) and brittle (we hard coded some script names, like index.js, index2.js, etc).

This updates the frontend bundle to include integrity= attributes in HTML script tags, and updates CSP header creation to extract those integrity hashes and whitelist them in the generated asset list.

The CSP header creation is also changed to keep a reference to the security headers certified alongside the assets. This ensures the security headers do not need to be recomputed with every asset, and clarifies that assets were certified with specific headers.

The CSP header error handling in the test suite is updated for better error reporting.

Firefox references:


🟡 Some screens were changed

This updates the way we create the CSP headers (and in particular, the
`script-src` clause).

Before this, and due to a (now resolved) bug in Firefox, we could not
specify `integrity=` attributes for whitelisting scripts in HTML.
Instead we implemented a work around where we injected a new inline
script (with known hash) which in turn loaded the actual JS script.

This was unconventional, somewhat unsafe (because it didn't actually
include the script's hash) and brittle (we hard coded some script names,
like `index.js`, `index2.js`, etc).

This updates the frontend bundle to include `integrity=` attributes in
HTML script tags, and updates CSP header creation to extract those
integrity hashes and whitelist them in the generated asset list.

The CSP header creation is also changed to keep a reference to the
security headers certified alongside the assets. This ensures the
security headers do not need to be recomputed with every asset, and
clarifies that assets were certified with specific headers.

The CSP header error handling in the test suite is updated for better
error reporting.

Firefox references:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1409200
* https://www.mozilla.org/en-US/firefox/116.0a1/releasenotes/
@nmattia nmattia marked this pull request as ready for review February 2, 2024 10:09
Copy link
Contributor

@frederikrothenberger frederikrothenberger left a comment

Choose a reason for hiding this comment

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

Thanks, lgtm!

src/vite-plugins/src/index.ts Show resolved Hide resolved
fn certified_asset(asset_name: &str, certificate_version: Option<u16>) -> Option<CertifiedAsset> {
/// Read an asset from memory, returning the associated HTTP code, content and full list of
/// headers that were certified with the asset.
fn get_asset(
Copy link
Contributor

Choose a reason for hiding this comment

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

Given that the CertifiedAssets struct holds the shared headers already, it would IMHO be nicer if the get_certified_asset function would include the shared headers directly.

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 thought about that at first and then found it confusing that sometimes the CertifiedAsset includes the shared headers, sometimes not. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

Simplest would be to just remove the concept of shared_headers altogether and just duplicate them among all assets.
I don't think we are resource constrained enough to justify the complexity of deduplication. But that should probably go into a different PR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fyi @frederikrothenberger : Nicolas and I had a discussion about shared_headers on slack last week, and I thought it is nice not to have them duplicated, hence the changes in this PR. But I don't feel strongly about it.

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 don't think we are resource constrained enough to justify the complexity of deduplication.

I agree

Copy link
Collaborator

@przydatek przydatek left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

fn certified_asset(asset_name: &str, certificate_version: Option<u16>) -> Option<CertifiedAsset> {
/// Read an asset from memory, returning the associated HTTP code, content and full list of
/// headers that were certified with the asset.
fn get_asset(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fyi @frederikrothenberger : Nicolas and I had a discussion about shared_headers on slack last week, and I thought it is nice not to have them duplicated, hence the changes in this PR. But I don't feel strongly about it.

@nmattia nmattia added this pull request to the merge queue Feb 5, 2024
Merged via the queue into main with commit da6341c Feb 5, 2024
63 checks passed
@nmattia nmattia deleted the nm-integrity-3 branch February 5, 2024 12:41
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

Successfully merging this pull request may close these issues.

3 participants