Credentials: I created the secure_headers library which essentially does the same thing. I also built the scala library in use at twitter today.
secure_headers used to have to_json
/from_json
functionality (pull request) but I removed it when I rewrote the library (for use at GitHub). This implementation would not be compatible with my implementation which was inspired by this proposal.
I think it would be better to collapse all directive source lists to a flat structure. i.e. instead of having sub elements for "allow" (an array), "self" (boolean), "unsafe-inline" (boolean), "unsafe-eval" (boolean), just have a directive accept an array containing those values. This model matches the spec more closely and in my experience just creates more confusion. While it does have the benefit of validation (against types like unsafe-inlien), it adds complexity.
Instead of:
"script-src": {
"allow": [
"https://www.google-analytics.com"
],
"self": true,
"unsafe-inline": false,
"unsafe-eval": false
},
I would suggest this format:
"script-src": [
"https://www.google-analytics.com",
"'self'",
"'unsafe-inline'",
"'unsafe-eval'"
],
Ruby has a clean way of building arrays of strings which makes the double-quote-single-quote pattern less ugly %w(https://www.google-analytics.com 'self' 'unsafe-inline' 'unsafe-eval')
. I'm not sure if php has this functionality.
"upgrade-insecure-requests": true
is 👍. The same would apply to block-all-mixed-content
and other boolean-like values.
👍 I love it. It's very close to what I implemented in the secure_headers rewrite (documentation)
Many people have found it convenient to use a tag helper for nonce'ing inline content. Maybe provide something similar? I used to have hash support but it didn't make it into the secure_headers rewrite.
// Let's add a nonce for inline JS
$nonce = $csp->nonce('script-src');
$body .= "<script nonce={$nonce}>";
$body .= $desiredJavascriptCode;
$body .= "</script>";
// Let's add a nonce for inline JS
$body .= nonced_javascript_tag($desiredJavascriptCode)
where nonced_javascript_tag
generates the tag and automatically appends the nonce to the policy.
Hey, thanks for the feedback! :)
block-all-mixed-content
is new to me. I'll see about putting that in too ASAP. :)This can easily be done with a templating engine (e.g. Twig). Maybe I'll bug @fabpot about it later? :)