Commit c59774a3 authored by Jake Jarvis's avatar Jake Jarvis 馃惣

simplified cloudflare worker for security headers

parent aefaeec3
......@@ -28,7 +28,7 @@ If you run your own server, these can be added by way of your Apache or nginx co
The following script can be added as a Worker and customized to your needs. Some can be extremely picky with syntax, so be sure to [read the documentation](https://www.netsparker.com/whitepaper-http-security-headers/) carefully. You can fiddle with it in [the playground](https://cloudflareworkers.com/), too. Simply modify the current headers to your needs, or add new ones to the `newHeaders` or `removeHeaders` arrays.
```js
let newHeaders = {
let addHeaders = {
"Content-Security-Policy": "default-src 'self'; upgrade-insecure-requests",
"Strict-Transport-Security": "max-age=1000",
"X-XSS-Protection": "1; mode=block",
......@@ -45,30 +45,32 @@ let removeHeaders = [
]
addEventListener("fetch", event => {
event.respondWith(addHeaders(event.request))
event.respondWith(fetchAndApply(event.request))
})
async function addHeaders(req) {
let response = await fetch(req)
let responseHeaders = new Headers(response.headers)
async function fetchAndApply(req) {
// Fetch the original page from the origin
let response = await fetch(request)
Object.keys(newHeaders).map(function(name, index) {
responseHeaders.set(name, newHeaders[name])
// Make response headers mutable
response = new Response(response.body, response)
// Set each header in addHeaders
Object.keys(addHeaders).map(function(name, index) {
response.headers.set(name, addHeaders[name])
})
// Delete each header in removeHeaders
removeHeaders.forEach(function(name){
responseHeaders.delete(name)
response.headers.delete(name)
})
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: responseHeaders
})
// Return the new mutated page
return response
}
```
Once you're done, you can analyze your website's headers and get a letter grade with [Scott Helme](https://scotthelme.co.uk/)'s awesome [Security Headers](https://securityheaders.com/) tool. His free [Report-URI](https://report-uri.com/) service is another great companion tool to monitor these headers and report infractions your users run into in the wild.
You can view my website's [full Worker script here](https://git.jarv.is/jake/jarv.is/blob/master/worker.js) and check out [the resulting A+ grade](https://securityheaders.com/?q=https%3A%2F%2Fjarv.is%2F)!
\ No newline at end of file
You can view my website's [full Worker script here](https://git.jarv.is/jake/jarv.is/blob/master/worker.js) and check out [the resulting A+ grade](https://securityheaders.com/?q=https%3A%2F%2Fjarv.is%2F)!
let newHeaders = {
"Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline' stats.jarv.is comments.jarv.is buttons.github.io platform.twitter.com cdn.syndication.twimg.com; style-src 'self' 'unsafe-inline' comments.jarv.is platform.twitter.com; img-src 'self' data: https:; font-src 'self' comments.jarv.is; object-src 'self'; media-src 'self'; base-uri 'self' stats.jarv.is; form-action 'self' platform.twitter.com syndication.twitter.com; frame-src 'self' www.youtube.com www.youtube-nocookie.com platform.twitter.com syndication.twitter.com codepen.io; frame-ancestors 'self'; worker-src 'none'; connect-src 'self' jarvis.report-uri.com stats.jarv.is comments.jarv.is api.github.com syndication.twitter.com; upgrade-insecure-requests; report-uri https://jarvis.report-uri.com/r/d/csp/enforce; report-to default",
"Report-To": "{\"group\":\"default\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://jarvis.report-uri.com/a/d/g\"}]}",
/**
* Cloudflare Worker to add security headers and remove S3 headers.
* https://jarv.is/notes/security-headers-cloudflare-workers/
*/
let addHeaders = {
"Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline' stats.jarv.is comments.jarv.is buttons.github.io platform.twitter.com cdn.syndication.twimg.com; style-src 'self' 'unsafe-inline' comments.jarv.is platform.twitter.com; img-src 'self' data: https:; font-src 'self' comments.jarv.is; object-src 'self'; media-src 'self'; base-uri 'self'; form-action 'self' platform.twitter.com syndication.twitter.com; frame-src 'self' www.youtube.com www.youtube-nocookie.com platform.twitter.com syndication.twitter.com buttons.github.io codepen.io; frame-ancestors 'self'; worker-src 'none'; connect-src 'self' csp.jarv.is jarvis.report-uri.com stats.jarv.is comments.jarv.is api.github.com syndication.twitter.com; upgrade-insecure-requests; report-uri https://csp.jarv.is/r/d/csp/enforce; report-to default",
"Report-To": "{\"group\":\"default\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://csp.jarv.is/a/d/g\"}]}",
"NEL": "{\"report_to\":\"default\",\"max_age\":604800}",
// "Strict-Transport-Security" : "max-age=1000",
"X-XSS-Protection": "1; mode=block; report=https://jarvis.report-uri.com/r/d/xss/enforce",
"X-XSS-Protection": "1; mode=block; report=https://csp.jarv.is/r/d/xss/enforce",
"X-Frame-Options": "SAMEORIGIN",
"X-Content-Type-Options": "nosniff",
"Referrer-Policy": "same-origin",
......@@ -29,24 +34,33 @@ let removeHeaders = [
]
addEventListener("fetch", event => {
event.respondWith(addHeaders(event.request))
event.respondWith(fetchAndApply(event.request))
})
async function addHeaders(req) {
let response = await fetch(req)
let responseHeaders = new Headers(response.headers)
async function fetchAndApply(request) {
// Ignore POST and PUT HTTP requests.
// https://github.com/cloudflare/worker-examples/blob/master/examples/security/ingore-post-and-put.js
if (request.method === 'POST' || request.method === 'PUT') {
return new Response('Sorry, that method isn\'t allowed here.',
{ status: 403, statusText: 'Forbidden' })
}
// Fetch the original page from the origin
let response = await fetch(request)
Object.keys(newHeaders).map(function(name, index) {
responseHeaders.set(name, newHeaders[name])
// Make response headers mutable
response = new Response(response.body, response)
// Set each header in addHeaders
Object.keys(addHeaders).map(function(name, index) {
response.headers.set(name, addHeaders[name])
})
// Delete each header in removeHeaders
removeHeaders.forEach(function(name){
responseHeaders.delete(name)
response.headers.delete(name)
})
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: responseHeaders
})
// Return the new mutated page
return response
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment