Description
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.