-
Notifications
You must be signed in to change notification settings - Fork 105
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
Allow enforced CSP and Report-Only at the same time #36
Comments
Definitely in scope, would be happy to support this, but it is going to require a big change, at least in terms of API, we should figure out how we want it to look first. Tagging in @graingert and @mozfreddyb. One option would be to add a second, parallel set of settings, e.g.: CSP_DEFAULT_SRC = '...'
CSP_RO_DEFAULT_SRC = '...'
CSP_IMG_SRC = '...'
CSP_RO_IMG_SRC = '...' Then It's verbose, I don't love it. The decorator would still need a keyword to decide which policy is being updated (or both?). But it is a way to do site-wide alternate policies. Doing that via decorator would be painful. Maybe instead of x number of settings, it makes sense to change it to one setting in a dict, in the style of other complex Django settings? e.g. CSP_POLICY = {
'default': {
'DEFAULT_SRC': "'self'",
'IMG_SRC': ["'self'", 'img-host.example.com'],
'REPORT_ONLY': False,
},
'test_new_policy': {
...,
'REPORT_ONLY': True,
}
}
# Optional setting, defaults to 'default'
CSP_POLICIES = ['default', 'test_new_policy'] It's a bigger API change, but maybe lets things be cleaner when building policies? And it condenses, rather than expands, the namespace. Alternate proposals? |
I think you want two policy dicts so as to reflect how the underlying headers operate: CSP_REPORT_ONLY_POLICY = {
'DEFAULT_SRC': "'*'",
}
CSP_POLICY = {
'DEFAULT_SRC': "'self'",
} |
CSP technically does allow multiple policies. Not sure exactly why you'd want to, but allowing |
In that case something like: CSP_POLICIES = [
{
'DEFAULT_SRC': "'*'",
},
{
'DEFAULT_SRC': "'self'",
'REPORT_ONLY': True
}
] Rather than using a dict and defining order in another setting |
Also the CSP specification is invalid according to http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
|
There is no precedent for an ordered list of dicts in the django settings. A dict allows these to be named, and a separate setting makes it easy to flip them on and off or reorder. |
It's not our job here to resolve issues between RFC2616 and CSP. |
I like @jsocol's original proposal, even though it is a bit verbose, but I prefer explicitly here. |
Yep, I like the nested dict idea, too. However, why use "DEFAULT_SRC" rather than "default-src"? The latter would copy the original header more closely. |
@mozfreddyb do you mean a nested dict or a parallel set of settings? @qll copying the style of other settings (e.g. |
Nested dict as in your very first comment, @jsocol. |
Love the nested dict idea. You should add support to the decorators as well to replace or append policies based on name. Knowing that there is support in the spec for multiple policies makes me question whether the CSP decorator (@csp) is adequately clear and explicit? It could be append CSP or replace CSP. I'd suggest clearing the existing CSP should be done through one and only one very clear path ( Does it also make sense to think about plugging into the And finally a thought on backwards compatibility for users: You can leave the current settings, just load them into the policy dict under the 'default' key. If the 'default' key is also explicitly defined, throw an error. Set |
Oh and this issue is super old. Would you like me to take this on? |
@DylanYoung if you have the time for it, please go for it. Regarding what you said...
Personally, I don't think that's necessary. I also don't think we need support for Yeah, I like your idea of backwards compatibility. We could first introduce the new policy dictionary but also allow loading of it, if it's specified. That way we can safely deprecate old settings and transition to the new settings format. Looking forward to reviewing your pull request! |
any update on this? Would be nice to have this in django core, which waits on resolve of this ticket. thanks. |
@hiren1771 Thanks for the ping. My time got swallowed by life recently, but I'll see if I can get to this soon. |
Got a little start on it. Not quite functional yet. Couple notes: NEW settings: CSP_POLICY_DEFINITIONS (dict) The template is used for appending policies. It will be used as the "base" of the new policy. Can be set to I opted to make Legacy settings are still supported and there's a toggle in the code to change their precedence after an initial deprecation period. |
thanks, is this ticket still the right approach to use, considering this comment from the django ticket: |
@hiren1771 Should be fine I think. Once it's coded, they can fold it into core. I'll keep that in mind while I'm refactoring though. |
Ah I see, this module is also a middleware, and so is SecurityMiddleware. If there is anything I can help with, let me know. I have never worked on django code base but can do general python. Thanks again for picking this ticket up. |
@hiren1771 Sweet. I think I'll have a working version tomorrow (maybe you could give it a test and see if it all works and makes sense to you?), but there will be few final decisions to be made. Pinging @jsocol @graingert @mozfreddyb to try to get some of those discussions rolling. In particular, there are a couple of "per policy" settings that aren't directives, report-only being one. Do we want to differentiate these somehow from the actual directives? As far as back compatibility goes, I think the easiest thing is to continue supporting mixed case, underscores, and hyphens, then just normalise in the backend. Does that make sense to everyone? (This way we can keep using kwargs too). |
Also, I think I need a bit of clarification on the spec. My reading is that multiple comma delineated values are permitted, but only one of each of the two headers. Is that correct? If not, then I think we have to impose that restriction anyways as I don't think Django's response supports multiple headers with the same key. |
All tests are passing now. Haven't written tests for the multi-policy case yet so there might still be some bugs lurking in there. Still have some cleanup to do, but we're close :) |
…/csp_select decorators
…/csp_select decorators
…/csp_select decorators
…CY_DEFINITIONS
This comment was marked as off-topic.
This comment was marked as off-topic.
I've opened a PR that addresses this in #219 and am looking for feedback. This is a backwards incompatible change and we plan to release this with a major version bump to 4.0 to signify this. I feel the settings change should be straight-forward and hopefully not a difficult upgrade path. To @DylanYoung:
I would very much welcome any review and feedback. Thank you. |
This is a backwards incompatible change. Also fixes mozilla#139, mozilla#191
This is a backwards incompatible change. Also fixes mozilla#139, mozilla#191
@robhudson @stevejalim Thank you for all your efforts on this. It has been a long time coming. I see that you responded to this ticket in hopes of getting content security policy built into django core: https://code.djangoproject.com/ticket/15727 Just putting that link here for visibility, since it is not the easiest thing to find. |
The CSP 1.0 specification allows this explicitly in the sixth paragraph of Section 3.3: http://www.w3.org/TR/CSP/#processing-model
An example is given, too: "For example, if a server operator is using one policy but wishes to experiment with a stricter policy, the server operator can monitor the stricter policy while enforcing the original policy."
This would require bigger changes to the way the middleware works (maybe a flag as a parameter to the decorators? ... something like only_report=True). If this is in scope for the middleware, I am willing to propose an implementation soon.
The text was updated successfully, but these errors were encountered: