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

Security header CSP: add nonce support #3

Open
maxvisser opened this issue May 6, 2021 · 17 comments
Open

Security header CSP: add nonce support #3

maxvisser opened this issue May 6, 2021 · 17 comments
Labels
feature request New feature or request

Comments

@maxvisser
Copy link

maxvisser commented May 6, 2021

My organization needs for compliancy a really secure CSP to be on our cloudfront distribution. Currently I host my index.html file on a API gateway instead of our s3 bucket to allow me add nonces to style an scripts blocks.

Lambda function I use on this API gate way is as follows:

const crypto = require('crypto')
const fs = require('fs')
const cheerio = require('cheerio')

exports.handler = (event, context, callback) => {
    const $ = cheerio.load(fs.readFileSync('./index.html').toString('utf-8'))
    const nonce = crypto.randomBytes(16).toString('base64')
    $('script').attr('nonce', nonce)
    $('style').attr('nonce', nonce)
    $('meta[property="csp-nonce"]').attr('content', nonce)

    callback(null, {
        statusCode: 200,
        headers: {
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'Content-Security-Policy': `default-src 'none'; img-src 'self'; script-src 'nonce-${nonce}' 'self'; 'nonce-${nonce}' 'self'; object-src 'none'`,
            'Content-Type': 'text/html; charset=utf-8',
            'Expires': '0',
            'Pragma': 'no-cache',
            'Referrer-Policy': 'same-origin',
            'Strict-Transport-Security': 'max-age=31536001; includeSubDomains',
            'X-Content-Type-Options': 'nosniff',
            'X-Frame-Options': 'DENY',
            'X-XSS-Protection': '1; mode=block'
        },
        body: $.html()
    })
}

This method is made by @csarkosh you can also read his medium post about this issue he tried to solve:
https://medium.com/@csarkosh/my-experience-getting-an-a-from-mozillas-observatory-tool-on-aws-f0abf12811a1

For my stack it would be really beneficial that cloudfront support adding a nonce to CSP headers natively.

Currently Cloudfront functions / Lambda edge let you only change viewer requests/viewer response. What I need is to be able to change the body of the origin response.

So that I can:
Scan the HTML file I get from S3 on <script> and <style> blocks
Add via the function a attribute to these blocks ex <style nonce="test">

So what I ask is to:
Response body manipulation from within a CloudFront Function and/or Lambda@Edge function. You fetch the content from cache or the origin and I want to be able to manipulate that response body inside a Cloudfront function before the response is sent to the client.

Edit 12-5-2021:
added more clarification based on comments below.

@dbrown-git dbrown-git added the feature request New feature or request label May 10, 2021
@dbrown-git
Copy link
Contributor

So the ask is for a way to generate cryptographically strong pseudorandom data? Similar to https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback

@maxvisser
Copy link
Author

maxvisser commented May 11, 2021

Currently Cloudfront functions / Lambda edge let you only change viewer requests/viewer response. What I need is to be able to change the body of the origin response.

So that I can:
Scan the HTML file I get from S3 on <script> and <style> blocks
Add via the function a attribute to these blocks ex <style nonce="test">

I am currently using the example provided by @csarkosh you can also read his medium post about this issue:
https://medium.com/@csarkosh/my-experience-getting-an-a-from-mozillas-observatory-tool-on-aws-f0abf12811a1

@dbrown-git
Copy link
Contributor

So the ask is for response body manipulation from within a CloudFront Function and/or Lambda@Edge function? You fetch the content from cache or the origin and the ask is to be able to manipulate that response body inside the function before the response is sent to the client?

@maxvisser
Copy link
Author

maxvisser commented May 12, 2021

Correct. It would open up a lot more options then adding nonces to script and style tags. You could for example rewrite all http: to https: in href="" and src="" attributes. @liulk tried that; described here. He was also running into this limitation.

@vasilkrastev90
Copy link

+1

1 similar comment
@gabriel-amram
Copy link

+1

@Aaronius
Copy link

Yes! This is very needed!

@b27cs
Copy link

b27cs commented Feb 25, 2022

+1 This is a critical functionality, and I was very surprised to see it's not possible to do it at the moment. Without being able to manipulate the body and add a nonce, there is no direct way to build a Cloudfront SPA with proper security header config without introducing an additional middleware component to handle the nonce

@ArmanNisch
Copy link

+500

@marcos-cassel-powerschool

+1

@lezixb
Copy link

lezixb commented Nov 14, 2023

+1
Needing similar capability natively on cloudfront

@james-certn
Copy link

Dropping this CSP injection approach article for anyone interested.

@maxvisser
Copy link
Author

maxvisser commented Feb 13, 2024

Dropping this CSP injection approach article for anyone interested.

Cool post! I would highly advice to look at the medium post of @csarkosh;
https://medium.com/@csarkosh/my-experience-getting-an-a-from-mozillas-observatory-tool-on-aws-f0abf12811a1

The solution proposed in the article of Kris Wong is not a catch-all solution. The main thing is that If you add script tags on runtime this would not work. An example I found with stylesheets is that Google Maps adds alot of stylesheets on runtime, even if your own application does not. It could still result in issues in production...

@james-certn
Copy link

james-certn commented Feb 13, 2024

My understanding was that adding the nonce to the page's script and style tags made it cascade into dynamically added script/style tags - so it would work fine for your suggested scenario?

@james-certn
Copy link

Found the reference from the bottom of this page:

When such a policy is set, modern browsers will execute only those scripts whose nonce attribute matches the value set in the policy header, as well as scripts dynamically added to the page by scripts with the proper nonce.

@janquijano
Copy link

Would love to have this feature in CloudFront

@janquijano
Copy link

If supporting it natively is not an option, even just including the body in the response event (viewer or origin) would help a lot. It would simplify the solution (Kris's) immensely. Having Lambda fetch the object from S3 and have to manually cache it seems a bit too much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

No branches or pull requests