Re: Django and CSP strict-dynamic

2017-05-22 Thread Adam Johnson
>
> I agree; note however, that nonces are part of CSP Level 2, which is in
> "W3C Recommendation" status


Ah, I am not familiar with all these standards, thanks for clarifying.

The first part I think Django should be involved in in generating the nonce
> (a simple base64(os.random(16)) and making it available from the request
> object. Doing this in SecurityMiddleware sounds natural.


Makes sense, also the middleware should be the thing adding the header.

The explicit way would be to add a `{% csp_nonce %}` template tag, which
> expands to `nonce=NONCE` if SecurityMiddleware if a nonce is available
> (SecurityMiddleware is enabled), and to nothing otherwise. Apps will need
> to annotate their tags with it, similarly to how `{% csrf_token %}` is used.
>

Agree with the logic around making it a conscious choice, auto-adding it
after the rendering is just leaving the security hole wide open as it's
impossible to tell what was part of the template and what is data that
potentially injected a 

Re: Django and CSP strict-dynamic

2017-05-16 Thread Ran Benita
OK, so to refocus the issue:

Using CSP nonces requires the following: any 

Re: Django and CSP strict-dynamic

2017-05-16 Thread Ran Benita
Hi Adam, thanks for your comments.

> Given that it's still a W3C draft I am not sure it should be added to 
Django core yet.

I agree; note however, that nonces are part of CSP Level 2, which is in 
"W3C Recommendation" status. Since support for nonces is a prerequisite for 
any of this, I'll refocus on just that part (in a separate message). After 
it's possible to handle the nonces, supporting strict-dynamic becomes 
possible. either in Django itself or in a third-party app.

> However it does seem that without a centralized solution for CSP nonces, 
they won't be usable with third party apps as you found with 
django-debug-toolbar.

Yes, this is the part where involvement from the framework is strictly 
required, I think.

> So I'm wondering, is your code public?

Not currently, I will polish it when I have time and publish it. However, 
as I said, it is very trivial, and doesn't do anything besides what I 
described in the post.

> And do you think it is worth trying to merge into django-csp, or would it 
be better as a standalone app?

It can certainly be added to django-csp, for visibility if nothing else, 
but in my opinion a standalone app would be nicer:

1. Whitelist policies and strict-dynamic are almost orthogonal; they cannot 
be combined in a single policy, since 'strict-dynamic' causes the whitelist 
directives in 'script-src' to be ignored. The django-csp configuration DSL 
is *mostly* useless for strict-dynamic.

2. I imagine a standalone package to have a simple "read short README, 
annotate 

Re: Django and CSP strict-dynamic

2017-05-15 Thread Adam Johnson
Hi Ran

Given that it's still a W3C draft I am not sure it should be added to
Django core yet. I don't know of any official policy around what Django
implements versus the W3C spec levels though.

However it does seem that without a centralized solution for CSP nonces,
they won't be usable with third party apps as you found with
django-debug-toolbar.

For web security in Django, I'd like to help get strict-dynamic available
in a third party app, django-csp or otherwise. So I'm wondering, is your
code public? And do you think it is worth trying to merge into django-csp,
or would it be better as a standalone app? (I'm not really familiar with
what django-csp does/does not do)

Adam

On 13 May 2017 at 11:16,  wrote:

> Hey,
>
> I'd like to discuss how Django might encourage and ease the use of CSP in
> the frontend. As Django is used more and more to drive complex web
> applications, I think this is of interest. (I tried to keep this short, but
> failed...).
>
> # CSP background
>
> CSP (Content Security Policy) is an elaborate mechanism which allows to
> attach a policy to a webpage, restricting the things it can do and the
> origins it can interact with. It is mainly meant to aid in the prevention
> of various code injection attacks. It is usually sent in the
> `Content-Security-Policy` header in the response to the HTML request.
> Please see here for more details: https://developer.mozilla.org/
> en-US/docs/Web/HTTP/CSP
>
> Currently, in order to have a secure policy you must write big
> white-lists, which does not lend itself well to automation by a framework.
> For example, here is the policy GitHub sends, which is relatively tame as
> far as these go:
>
> default-src 'none';
> base-uri 'self';
> child-src render.githubusercontent.com;
> connect-src 'self' uploads.github.com status.github.com
> collector.githubapp.com api.github.com www.google-analytics.com
> github-cloud.s3.amazonaws.com github-production-repository-f
> ile-5c1aeb.s3.amazonaws.com github-production-user-asset-7
> 9cafe.s3.amazonaws.com wss://live.github.com;
> font-src assets-cdn.github.com;
> form-action 'self' github.com gist.github.com; frame-ancestors 'none';
> img-src 'self' data: assets-cdn.github.com identicons.github.com
> collector.githubapp.com github-cloud.s3.amazonaws.com *.
> githubusercontent.com;
> media-src 'none';
> script-src assets-cdn.github.com;
> style-src 'unsafe-inline' assets-cdn.github.com
>
> The django-csp project (https://github.com/mozilla/django-csp) helps with
> generating these in Django. However, maintaining, deploying and monitoring
> it is quite a major effort, depending on the complexity of the site.
>
> # The strict-dynamic directive
>
> Because of this, the upcoming version of the CSP standard (Level 3,
> https://www.w3.org/TR/CSP/) includes a new `script-src` directive called
> `strict-dynamic`. It has its own website:
> https://csp.withgoogle.com/docs/index.html
>
> The idea here is that you send a policy like this:
>
> script-src 'nonce-{random}' 'strict-dynamic';
>
> where `{random}` is some token that is randomly generated in each request,
> e.g. `hM6RAC4rgxYFk01gbbfcKw==`. Next, each script included in the page
> must be decorated with a `nonce` attribute, using the nonce sent in the
> header:
>
>  src="/path/to/script.js">
>
> foo()
>
> What the `strict-dynamic` means, is that any script trusted with the nonce
> is transitively trusted to load its own scripts dynamically. Thus, most of
> the XSS protection remains, however the maintenance burden drops
> significantly, and it becomes much more amenable to automation in a
> framework.
>
> # Browser support and backward compatibility
>
> `strict-dynamic` is already supported in recent versions of Firefox and
> Chrome, and is "under consideration" by Edge:
> https://blogs.windows.com/msedgedev/2017/01/10/edge-csp-2/
>
> The CSP Level 3 spec is still a draft, but from what I could gather they
> are aiming to finalize it in "Q3 2017":
> https://rawgit.com/w3c/webappsec/master/admin/webappsec-charter-2017.html
>
> What about browsers which does not support `strict-dynamic`, but only
> support older CSP versions? With the policy I gave above, everything will
> be blocked (if nonces are not supported), or transitive scripts will be
> blocked (if nonces are supported). To workaround this, `strict-dynamic`
> has the behavior of disabling/ignoring other directives if it is
> understood. So we can send a policy like this instead:
>
> script-src 'nonce-{random}' 'unsafe-inline' 'unsafe-eval'
> 'strict-dynamic' https: http:;
>
> In browsers that support CSP3, it will be interpreted as
>
> script-src 'nonce-{random}' 'strict-dynamic' 'unsafe-eval'
>
> In browsers that support CSP2:
>
> script-src 'nonce-{random}' 'unsafe-eval' https: http:;
>
> In browsers that support CSP1:
>
> script-src 'unsafe-inline' 'unsafe-eval' https: http:;
>
> In all cases it should work out.
>

Django and CSP strict-dynamic

2017-05-13 Thread ran234
Hey,

I'd like to discuss how Django might encourage and ease the use of CSP in
the frontend. As Django is used more and more to drive complex web
applications, I think this is of interest. (I tried to keep this short, but
failed...).

# CSP background

CSP (Content Security Policy) is an elaborate mechanism which allows to
attach a policy to a webpage, restricting the things it can do and the
origins it can interact with. It is mainly meant to aid in the prevention
of various code injection attacks. It is usually sent in the
`Content-Security-Policy` header in the response to the HTML request.
Please see here for more details: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

Currently, in order to have a secure policy you must write big
white-lists, which does not lend itself well to automation by a framework.
For example, here is the policy GitHub sends, which is relatively tame as
far as these go:

default-src 'none';
base-uri 'self';
child-src render.githubusercontent.com;
connect-src 'self' uploads.github.com status.github.com 
collector.githubapp.com api.github.com www.google-analytics.com 
github-cloud.s3.amazonaws.com 
github-production-repository-file-5c1aeb.s3.amazonaws.com 
github-production-user-asset-79cafe.s3.amazonaws.com wss://live.github.com;
font-src assets-cdn.github.com;
form-action 'self' github.com gist.github.com; frame-ancestors 'none';
img-src 'self' data: assets-cdn.github.com identicons.github.com 
collector.githubapp.com github-cloud.s3.amazonaws.com 
*.githubusercontent.com;
media-src 'none';
script-src assets-cdn.github.com;
style-src 'unsafe-inline' assets-cdn.github.com

The django-csp project (https://github.com/mozilla/django-csp) helps with
generating these in Django. However, maintaining, deploying and monitoring
it is quite a major effort, depending on the complexity of the site.

# The strict-dynamic directive

Because of this, the upcoming version of the CSP standard (Level 3,
https://www.w3.org/TR/CSP/) includes a new `script-src` directive called
`strict-dynamic`. It has its own website:
https://csp.withgoogle.com/docs/index.html

The idea here is that you send a policy like this:

script-src 'nonce-{random}' 'strict-dynamic';

where `{random}` is some token that is randomly generated in each request,
e.g. `hM6RAC4rgxYFk01gbbfcKw==`. Next, each script included in the page
must be decorated with a `nonce` attribute, using the nonce sent in the
header:



foo()

What the `strict-dynamic` means, is that any script trusted with the nonce
is transitively trusted to load its own scripts dynamically. Thus, most of
the XSS protection remains, however the maintenance burden drops
significantly, and it becomes much more amenable to automation in a
framework.

# Browser support and backward compatibility

`strict-dynamic` is already supported in recent versions of Firefox and
Chrome, and is "under consideration" by Edge:
https://blogs.windows.com/msedgedev/2017/01/10/edge-csp-2/

The CSP Level 3 spec is still a draft, but from what I could gather they
are aiming to finalize it in "Q3 2017":
https://rawgit.com/w3c/webappsec/master/admin/webappsec-charter-2017.html

What about browsers which does not support `strict-dynamic`, but only
support older CSP versions? With the policy I gave above, everything will
be blocked (if nonces are not supported), or transitive scripts will be
blocked (if nonces are supported). To workaround this, `strict-dynamic`
has the behavior of disabling/ignoring other directives if it is
understood. So we can send a policy like this instead:

script-src 'nonce-{random}' 'unsafe-inline' 'unsafe-eval' 
'strict-dynamic' https: http:;

In browsers that support CSP3, it will be interpreted as

script-src 'nonce-{random}' 'strict-dynamic' 'unsafe-eval'

In browsers that support CSP2:

script-src 'nonce-{random}' 'unsafe-eval' https: http:;

In browsers that support CSP1:

script-src 'unsafe-inline' 'unsafe-eval' https: http:;

In all cases it should work out.

Note however, that the following things cannot be used and must be
replaced by modern equivalents:

- `javascript:` URIs.
- Inline event handlers, e.g. `onclick="foo()"`.

For real-world usage, according to
https://security.googleblog.com/2016/09/reshaping-web-defenses-with-strict.html
Google are already using `strict-dynamic` in several of their
applications, e.g. see the header sent by https://photos.google.com/.

# Interaction with existing white-list based policies

White-list based policies generated by e.g. django-csp are still useful,
as they provide a different range of protections.

It is possible to send multiple policies, in which case they are all
enforced. Therefore, `strict-dynamic` can be treated as just an additive
measure.

Since Django does not support sending multiple headers with the same key,
it is possible instead to ', '.join() them, as is standard in HTTP.

# Integration with Django

I wrote a Django app