-
Notifications
You must be signed in to change notification settings - Fork 703
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
Add security headers to minimize XSS damage #292
Conversation
@xPaw, I rebased this to merge conflicts :-) |
@@ -91,6 +97,7 @@ function index(req, res, next) { | |||
config | |||
); | |||
var template = _.template(file); | |||
res.setHeader("Content-Security-Policy", "default-src *; style-src * 'unsafe-inline'; script-src 'self'; reflected-xss block"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this policy! A few minor comments/questions:
Content-Security-Policy
is defined on page-by-page basis. Any reason why you put it here instead of inside yourallRequests
function?*
is the default value for everything so we don't need to specify it fordefault-src
. Was there a specific reason why you did so?- I'm not sure I fully understand
reflected-xss block
: is it to enforce Chrome's filter against executing code that exists in the URL (for example) onto all browsers that would not enforce it by default? - It's possible that some or all of the following directives could be added, provided that I'm not entirely wrong:
- Any reason against
connect-src 'self';
considering how the server connects to the client (at least currently)? - I think we could set
child-src 'none'; object-src 'none';
as well, as I don't think we need framed content or Flash content or etc. - We can set
form-action 'self';
as well, or maybe evenform-action 'none';
as none of the forms get actually submitted. - We might be able to set
frame-ancestors 'none';
but maybe that could restrict usage for some users? (Thinking of the integrations like Bytesized or Cozy or whatever, maybe someone does crazy stuff to display their apps?) - We can set
media-src 'self'
as we don't embed videos or similar (but we do load one sound from within the app)
- Any reason against
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure there's any need to send CSP on all requests (all other requests besides index.html would be static content).
I'm not sure I fully understand reflected-xss block
reflected-xss : Instructs a user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standard X-XSS-Protection header.
I've also didn't set extra hardened directives because I don't know what we would want to allow for eventual plugins to do.
*
is the default value for everything so we don't need to specify it for default-src
Explicitness. We could eventually set it to self
instead, and configure other directives as needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure there's any need to send CSP on all requests (all other requests besides index.html would be static content).
Yeah OK, we'll adjust later if necessary.
I know that we essentially only send index and then the websocket takes over, but I'm thinking that other fallbacks from Socket.io might be worth "policying". But again, I don't think Socket.io would send this policy even if we set if with all requests (because it does go through Express).
reflected-xss : Instructs a user agent to activate or deactivate any heuristics used to filter or block reflected cross-site scripting attacks, equivalent to the effects of the non-standard X-XSS-Protection header.
OK so basically it's unnecessary in Chrome because filters are already enabled, but I don't know for other browsers.
I've also didn't set extra hardened directives because I don't know what we would want to allow for eventual plugins to do.
Agreed, but what about hardening at the moment and adapting when packages are a reality (or start to be one)?
After all, it's not set in stone, and some directives of the policy might not change anyway (especially connect-src
and form-action
, maybe child-src
).
Explicitness. We could eventually set it to
self
instead, and configure other directives as needed.
Good point, to keep in mind.
I'm essentially 👍 but I would prefer if we harden things as suggested in the comments before merging this PR. Again, nothing set in stone, totally OK to re-evaluate when plugins show up, but in the meantime, there is no need to keep the doors open. |
For the record, I had to catch up on the details of CSP before reviewing this, and if someone is looking for a good intro, http://www.html5rocks.com/en/tutorials/security/content-security-policy/ is really good. |
I've added |
@@ -14,7 +14,7 @@ function uri(text) { | |||
return url; | |||
} | |||
var split = url.split("<"); | |||
url = "<a href='" + split[0].replace(/^www/, "//www") + "' target='_blank'>" + split[0] + "</a>"; | |||
url = "<a href='" + split[0].replace(/^www/, "//www") + "' target='_blank' rel='noopener'>" + split[0] + "</a>"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://mathiasbynens.github.io/rel-noopener/
Thought it would be a good idea to include along with referrer no-referrer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great read! And great idea!
Looks all good to me, 👍 @astorije did you still want to hold the merge? |
Nop, let's do this! |
Add security headers to minimize XSS damage
This disallows execution of scripts from other domains, inline scripts and use of eval. Also adds
X-Content-Type-Options: nosniff
on all requests.