Skip to content
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

Feature request: allow use of '{host}' in directives, replaced by request.get_host() #72

Open
davidwtbuxton opened this issue Sep 29, 2016 · 7 comments
Labels
feature new features

Comments

@davidwtbuxton
Copy link

davidwtbuxton commented Sep 29, 2016

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.

@davidwtbuxton
Copy link
Author

Any interest?

@EnTeQuAk
Copy link
Contributor

EnTeQuAk commented Nov 4, 2016

Hey, sorry for the very late answer.

That's a wonderful idea but I'm not sure if it's reasonable to provide this in django-csp by default. Currently I'm more for adding this as a recipe in the docs so people can implement it on their own and maybe add some more verification steps to it depending on the environment they're in.

I'd like to avoid any features that make the config more dynamic than it already is given the nature of csp to be as restrictive as possible.

How does that sound to you?

@davidwtbuxton
Copy link
Author

I would prefer that django-csp includes the feature I suggested, so that I don't have to write my own implementation and track any changes in django-csp. I believe this would be a really useful addition to how webmasters configure csp.

But of course I appreciate the position that this is an extension to how csp works at present, so is outside django-csp's remit. In a perfect world (due any day now) csp itself would have a 'host' keyword that does what I want.

If you think this would be useful as a recipe, suggestions for how to add it to the docs? I don't see a recipes page at present.

Thanks,

David B.

@EnTeQuAk
Copy link
Contributor

EnTeQuAk commented Nov 7, 2016

Indeed we don't have that currently. There's still some work to do on the docs so if you let me I can integrate your snippet in the next few days in the docs.

I mean, I don't say it's not useful I just think it's out of scope and can easily be misconfigured. If people will be using that snippet all the time there's nothing stopping us from getting it into the core.

@EnTeQuAk EnTeQuAk self-assigned this Nov 7, 2016
@EnTeQuAk EnTeQuAk removed their assignment Nov 28, 2017
@DylanYoung
Copy link
Contributor

I'm very much in favour of this, though it should be strongly noted in the docs as a potential footgun. What I'd prefer (instead of hardcoding a particular implementation) is a mapping in the settings from a format key to a callable that takes a request and response and returns a string.

Maybe making it a different middleware would be wise as well.

@g-k g-k added the feature new features label Jul 27, 2021
DylanYoung added a commit to DylanYoung/django-csp that referenced this issue May 25, 2022
DylanYoung added a commit to DylanYoung/django-csp that referenced this issue May 25, 2022
@DylanYoung
Copy link
Contributor

I've created a POC here:

https://github.com/DylanYoung/django-csp/tree/GH-72

I'd like to add some more tests and change the defaults, but I'd rather wait until #36 is merged before going any deeper as there are some changes there. Should be usable as is for what you need @davidwtbuxton . The current implementation doesn't handle a missing HTTP_HOST though, so you might to change it to handle that gracefully, default to self or something (not sure if that would happen in the wild).

DylanYoung added a commit to DylanYoung/django-csp that referenced this issue May 25, 2022
DylanYoung added a commit to DylanYoung/django-csp that referenced this issue May 25, 2022
DylanYoung added a commit to DylanYoung/django-csp that referenced this issue May 25, 2022
DylanYoung added a commit to DylanYoung/django-csp that referenced this issue May 26, 2022
@some1ataplace

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature new features
Projects
None yet
Development

No branches or pull requests

5 participants