-
Notifications
You must be signed in to change notification settings - Fork 108
Description
Hi,
I want to use CSP with a directive that matches a script path and whatever the current request's host is, instead of having to explicitly list all the possible hosts.
So in your Django settings you could have:
CSP_DEFAULT_SRC = ["'none'"]
CSP_SCRIPT_SRC = ['{host}/app.js']
And at runtime this would be transformed by django-csp, substituting the host name from the request. A request to a server at example.com would generate a response with a header like:
Content-Security-Policy: default-src 'none'; script-src example.com/app.js
While a request to the same application running on localhost:8000 would generate a response with a header like:
Content-Security-Policy: default-src 'none'; script-src localhost:8000/app.js
On Google App Engine, a site is available at potentially any number of different host names, because every version of a deployed application can have its own link. For example if I upload 3 versions called "v1", "v2", and "foo-bar-baz" to an app called "my-app", then all of these would be valid host names:
- my-app.appspot.com
- v1-dot-my-app.appspot.com
- v2-dot-my-app.appspot.com
- foo-bar-baz-dot-my-app.appspot.com
When writing a CSP directive, this means you cannot know all the host names that the site will use, so while you could use script-src 'self'
, there's no way of writing a directive that includes a path that covers all host names. E.g. you can't do script-src 'self'/app.js
, you need to do script-src my-app.appspot.com/app.js v1-dot-my-app.appspot.com/app.js v2-dot-my-app.appspot.com/app.js foo-bar-baz-dot-my-app.appspot.com/app.js
.
In addition, you don't want to use a wildcard like script-src *.appspot.com/app.js
because there are many other sites on appspot.com which you don't want to whitelist.
So what would be nice would be a way to substitute the host name from the request, and combine that with the path in a directive. I was thinking to allow a special string in "CSP_*_SRC" settings, {host}
, which the middleware would replace with the host name taken from the request.
Another nice thing about this is it makes it easy to support requests to the local development server on "localhost:8000" without needing to add that explicitly to directives.
I have a proof of concept middleware which should help explain what on earth I am on about.
Any interest in having a feature like this in django-csp itself?
Thanks,
David B.