Skip to content

Instantly share code, notes, and snippets.

@g-wilson
Last active September 27, 2017 17:09
Show Gist options
  • Save g-wilson/c59f116d67c14651a9f78cd8401f4d31 to your computer and use it in GitHub Desktop.
Save g-wilson/c59f116d67c14651a9f78cd8401f4d31 to your computer and use it in GitHub Desktop.
Lambda@Edge function for Cloudfront which adds web security headers to static sites hosted with S3 + Cloudfront
/**
* This script is to be deployed as a Lambda@Edge function for AWS Cloudfront which
* adds necessary web security headers to static sites hosted with S3 + Cloudfront.
* This behaviour is not currently (2017-09-27) supported as a configuration option in S3 or Cloudfront.
*
* Lambda trigger event name: "CloudFront Viewer Response"
* Installation instructions: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-create-functions.html
*
* Extras not currently included:
*
* More Content Security Policy directives: https://content-security-policy.com/
*
* Pinned Keys are the Amazon intermediate: "s:/C=US/O=Amazon/OU=Server CA 1B/CN=Amazon" and LetsEncrypt "Let’s Encrypt Authority X1 (IdenTrust cross-signed)"
* headers['Public-Key-Pins'] = 'pin-sha256="JSMzqOOrtyOT1kmau6zKhgT676hGgczD5VMdRMyJZFA="; pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; max-age=1296001; includeSubDomains';
* (from: https://medium.com/@tom.cook/edge-lambda-cloudfront-custom-headers-3d134a2c18a2)
*
*/
'use strict'
const headers = {
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"Content-Security-Policy": [
"default-src 'none'",
"img-src 'self' data:",
"script-src 'self'",
"style-src 'self' https://fonts.googleapis.com",
"font-src 'self' https://fonts.gstatic.com",
"connect-src 'self'",
"media-src 'self'",
],
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "same-origin",
}
exports.handler = (event, context, callback) => {
callback(null, Object.keys(headers).map(hdr => ([ {
key: hdr,
value: Array.isArray(headers[hdr]) ? headers[hdr].join('; ') : headers[hdr],
} ])).reduce((obj, header) => {
obj.headers[header[0].key.toLowerCase()] = header
return obj
}, event.Records[0].cf.response))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment