cookiecutter / cookiecutter-django

Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.
https://cookiecutter-django.readthedocs.io
BSD 3-Clause "New" or "Revised" License
12.03k stars 2.88k forks source link

Traefik uses weak security settings by default #2841

Open jameswilliams1 opened 4 years ago

jameswilliams1 commented 4 years ago

tl;dr

Traefik is configured using its default settings leaving it more open to attacks - a few tweaks could bring it up to production standard and lower the attack surface. See this report of a site made using cookiecutter-django.

Security Issues

Fixes needed

Also slightly related, not big enough for its own issue: copying the traefik.yaml as part of the docker build is not really ideal as it prevents hot-reloading the config (a nice feature of traefik) - you need to completely rebuild to update config. Simply mounting the file read-only in production.yml would fix this.

I can make a PR if someone seconds these changes.

browniebroke commented 4 years ago

Thanks for raising this issue. We're open to pull request(s) to fix these security issues. Some are definitely non-obvious and less experienced people would benefit a lot from someone experienced with Traefik tuning these.

While you're on the subject of tuning Traefik, you might also be interested in #1992. A fix was started in #2217 but it somewhat stalled now, and it would be great to fix it.

jameswilliams1 commented 4 years ago

@browniebroke I have an updated config for this that gets an A+ on ssllabs now, I will make a PR shortly. Worth also mentioning a major improvement to security would be to add a Content-Security-Policy header, basically only allowing scripts/styles/ajax calls from certain domains (majorly reduces the risk of XSS attacks, more details here.

Ideally you would block everything and whitelist the bare minimum, but for cookicutter this would be far too restrictive for end users as we don't know what code/libraries they will add. I was thinking what could be good: a fairly permissive policy that works with Bootstrap/jQuery/other cookicutter tools out of the box and allows everything by default from the current site. It's not the optimal security settings, but as a default its as good as we can get it, and more than enough for most websites, thoughts?

jameswilliams1 commented 4 years ago

I'll look into the traefik non-root as well as that's something that's been bothering me for a while.

browniebroke commented 4 years ago

Oh yes, CSP would be very nice, although it's a separate issue.

I was thinking what could be good: a fairly permissive policy that works with Bootstrap/jQuery/other cookicutter tools out of the box and allows everything by default from the current site. It's not the optimal security settings, but as a default its as good as we can get it, and more than enough for most websites.

If we could provide a basic setup, it would be a massive improvement, yes. I like the approach you suggest, I think it's important to not trip people unfamiliar with it too quickly while providing a basic level of security. Feel free to submit a PR directly (or open a separate issue if you think it'll take you longer to implement).

jameswilliams1 commented 4 years ago

Will do, I'll look at adapting the one I have for my site and making it a little more permissive (as its tuned specifically for my site ATM). Probably best I add a small section to the readme for users - essentially if you want to use a script from a different CDN you would also have to add the domain to the CSP header in traefik.yml to enable it to execute.

manast1 commented 3 years ago

I'll look into the traefik non-root as well as that's something that's been bothering me for a while.

Sorry if im bothering or this is the wrong place - this is my first Github post. @jameswilliams1 I cant find a bind mount of the dockersocket to the traefik container in your pulls or files. How can traefik work without binding docker.sock? As traefik usually is the entrypoint to everything else, I want to drop root privileges entirely if possible.

jameswilliams1 commented 3 years ago

I'll look into the traefik non-root as well as that's something that's been bothering me for a while.

Sorry if im bothering or this is the wrong place - this is my first Github post. @jameswilliams1 I cant find a bind mount of the dockersocket to the traefik container in your pulls or files. How can traefik work without binding docker.sock? As traefik usually is the entrypoint to everything else, I want to drop root privileges entirely if possible.

* chaged to non privileged ports

* set socketbind to read only

* started traefik with unprivileged user (through Dockerfile or docker-compose)
  Once in non-root mode, traefik is unable to use the socket (permission denied).
  Can you give me a hint what I'm overseeing?

I'd avoid mounting the sock for a prod deployment, it gives root access to the host. You don't need to use a sock with Traefik unless you have multiple containers for each service that need to be resolved dynamically (really more useful for K8s than docker-compose) but if needed go with a proxy like this so Traefiks access is read only. Whether the docker user is root or not doesn't matter if you have sock access as you could just create a new container and chroot it to / on the host/any other container anyway.

In answer to the last question, sockets require write access to do anything. If you're trying to prevent malicious creation/deletion of containers you need a proxy as above.

manast1 commented 3 years ago

Tanks alot @jameswilliams1 - didn't expect that fast response :) Ok got it & nice illustration of madness (chroot to / ). Docker and Traefik docs confused me for the same reason you stated (doesn't protect socket from captured container root or non-root). I'll try the proxy aproach and hope it supports my docker-api version 1.41 (newest). I love the idea of services describing themself and their routing. Most docker/traefik tutorials use dynamic configuration. I don't have any scaling/k8s/swam yet, but I hope the dynamic configuration helps me later on once I build something useful / decide to learn more /switch to swarm. edit/feedback: traefik now runs rootless with the proxy solution.