django-admin startproject settings.py has some security holes

282 views
Skip to first unread message

Bobby Mozumder

unread,
Oct 10, 2019, 3:41:53 PM10/10/19
to Django developers (Contributions to Django itself)
In particular, they include settings that shouldn’t be stored in a git repo such as SECRET_KEY and database passwords. You’ll find these kinds of settings in git repos all the time.

Really the default django-admin startproject shouldn’t have a single settings.py that people include in their git repos, but instead a python settings module, with a base.py, development.py, staging.py, and production.py. An __init__.py reads base.py and one of development/staging/production based on ENV variables (defaulting to development if no ENV variable).

Additionally, startproject should add a .gitignore in the root directory to not include development/staging/production settings files.

I get that this might not be absolutely necessary but I think these are the kinds of defaults that make practical real-world use more secure, as well as standardizing workflow for more advanced production usage.

Is this something agreeable? I can put together a solution if people like this.

-bobby

Ehigie Aito

unread,
Oct 10, 2019, 4:20:08 PM10/10/19
to django-d...@googlegroups.com
Hello Bobby,
I think this should be added to a best practises documentation and not codified in Django. As I feel that would be overkill. 

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/320B70FD-BDC1-445D-B72B-0CD0BA736B88%40gmail.com.

Christian González

unread,
Oct 11, 2019, 7:14:09 AM10/11/19
to django-d...@googlegroups.com

Hi, may I disagree - I set up projects very often (for testing a package), and I always feel a bit awkward because of that monolithic settings.py file.

I can really support Bobby's idea, even if development/staging/production may be a bit overkill. Having a practical standard which ensures good practice from the start is a good thing. And OTOH, it won't hurt anyone if these files are there.

As there was another discussion earlier about "declarative" settings - maybe it would be helpful to exclude some of the settings from settings.py which is code, not declaration. SECRET_KEY could be anywhere by default, it doesn't have to be in an executable .py file. But this would mean to change Django's code to read it before or after importing settings.py.

+1 for a .gitignore file too.

Christian

Am 10.10.19 um 22:18 schrieb Ehigie Aito:
pEpkey.asc

Nick Sarbicki

unread,
Oct 11, 2019, 7:40:26 AM10/11/19
to Django developers (Contributions to Django itself)
I strongly disagree with this.

I've not seen a common standard between companies when it comes to settings in Django and for good reason. Different companies employ different standards and practices when it comes to configuration and security. Enforcing an arbitrary standard - such as a settings file for each env - is too opinionated for me and would often involve extra work on setup to remove this initial way of doing things.

Likewise in my experience ignoring settings files is actually quite rare. Most companies store secrets external to the settings file and prefer to keep their settings in git. Adding a .gitignore with the settings files would actually cause issues on future projects where you aren't expecting this.

As mentioned this isn't necessarily to say having multiple settings files or ignoring settings files are bad in an individual project. But that every project has its own way of handling configuration and secrets, so enforcing the standard you follow on everyone else - not because it is the best possible way of doing things, but because it is how you do things - is unlikely to be a popular move.

Adapting your settings configuration to the way you work is a small amount of work - Django does a good job at the moment of staying unopinionated on this whilst giving you what you need to get going.

On the SECRET_KEY. It is true that many people commit their SECRET_KEY into the repo. But in the same way that you often get people committing DB credentials and API keys. It is not a frameworks job to inform you of every security malpractice (although Django does a good job of this already), it is up to the developer to understand what they are doing. Despite this there is extensive documentation on the SECRET_KEY needing to be secret, mentioned both in the settings documentation and the deployment checklist. There is even a comment above this setting explicitly stating that it should be kept secret in production.

Assuming Django's startproject command aims to have a fully functioning project from the get go - which means it needs a SECRET_KEY - then I think this is a pretty good compromise as is.

- Nick


Florian Apolloner

unread,
Oct 11, 2019, 7:41:59 AM10/11/19
to Django developers (Contributions to Django itself)


On Thursday, October 10, 2019 at 9:41:53 PM UTC+2, Bobby Mozumder wrote:
Additionally, startproject should add a .gitignore in the root directory to not include development/staging/production settings files.

I am very much against creating a .gitignore as part of startproject. Also I do check my production settings file into version control because all the sensitive data comes from the environment, not from the code.

Mariusz Felisiak

unread,
Oct 11, 2019, 7:45:38 AM10/11/19
to Django developers (Contributions to Django itself)
Hi,

    I don't agree that Django should force pattern with multiple settings files (base, development, staging, and production) there is many ways to keep secrets and probably a production.py settings file is not the best one (IMO). Everything depends on a project (not all of them have such environments). You can always use your own project template if you don't like the builtin project template (see https://docs.djangoproject.com/en/2.2/ref/django-admin/#startproject). Also including `.gitignore` would be confusing, we cannot assume that all projects use the same structure.

Best,
Mariusz

Ehigie Aito

unread,
Oct 11, 2019, 8:00:03 AM10/11/19
to django-d...@googlegroups.com
This feature should be filled under a "nice to have" and not a "must have". 

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.

Carlton Gibson

unread,
Oct 11, 2019, 8:21:45 AM10/11/19
to Django developers (Contributions to Django itself)
I can see a How-To explaining different patterns here being a valid addition to the docs.

FWIW, there’s a PR to ease/enable SECRET_KEY rotation. It might mitigate some of the issues with first committing sensitive values to git when it lands. https://code.djangoproject.com/ticket/30360

Ehigie Aito

unread,
Oct 11, 2019, 10:29:51 AM10/11/19
to django-d...@googlegroups.com
Exactly, I believe a best practices section should be added to the already robust Django documentation. Something akin to the Two Scoops of Django book. That would be better than focusing a pattern on everyone.

On Fri, 11 Oct 2019, 13:21 Carlton Gibson, <carlton...@gmail.com> wrote:
I can see a How-To explaining different patterns here being a valid addition to the docs.

FWIW, there’s a PR to ease/enable SECRET_KEY rotation. It might mitigate some of the issues with first committing sensitive values to git when it lands. https://code.djangoproject.com/ticket/30360

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.

Carlton Gibson

unread,
Oct 11, 2019, 11:00:59 AM10/11/19
to Django developers (Contributions to Django itself)
It's just scope:

   * Not clear we need to _replace_ the space for books, and blog posts, and so on, in the main docs. 

and bandwidth:

   * These things are difficult to get right, and it needs someone to do them. (PRs always warmly received!)

On balance, I have to say, I think the default project template does very well. 
Taking a beginner, say, and adding, "As well as the million things you're already dealing with, there are these things called environment variable and..." is a step I'd be very cautious about taking. 

Yes, granted, for professional deployment, you might want different — but we have to serve everyone. 

Taymon A. Beal

unread,
Oct 21, 2019, 8:48:59 AM10/21/19
to Django developers (Contributions to Django itself)
Is the requirement here to avoid introduce additional barriers to getting up and running in local development, or to deploying a site so that it's accessible from the public internet?

Both of these are important goals, but trading off security against the latter worries me. I don't think we're doing beginners any favors if we make it easier for them to deploy sites with security issues, especially since they won't be in a good position to appreciate the consequences. Ideally we'd make it easy for beginners to deploy sites without security issues, but that's a hard problem given the diversity of production environments; in the meantime, I think we need to accept the reality that figuring out how to store secrets *is* a prerequisite to deploying Django in production, notwithstanding how much we wish it weren't.

I'd be interested in trying to contribute a solution more secure than the status quo without introducing more barriers to local development, if it would have a chance of being accepted.

Taymon

Josh Smeaton

unread,
Oct 23, 2019, 10:45:05 PM10/23/19
to Django developers (Contributions to Django itself)
A quick idea from the top of my head, is to change the assignment of SECRET_KEY in the generated settings to something like:

SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "insecure-<generatedvalue>")

It signals that secrets in the environment are a good idea, that the default generated value is insecure, and it still has a random part so that default sites aren't automatically hackable when deployed. There's no impact to people just getting started.

We could go a small step forward and use `check --deploy` to check for the substring `insecure` (even though I believe the KEY is technically bytes?).

Just throwing something out there.

Olivier Dalang

unread,
Oct 24, 2019, 6:32:19 PM10/24/19
to django-d...@googlegroups.com
Hi,

Just a reminder about this page in the docs: https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
It basically already covers it all. Maybe a direct link to that page from the settings file would be good enough?

Cheers,

Olivier

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.

Adam Johnson

unread,
Nov 16, 2019, 10:14:32 AM11/16/19
to django-d...@googlegroups.com

Taymon A. Beal

unread,
Dec 29, 2019, 2:44:54 AM12/29/19
to django-d...@googlegroups.com
The number of default-generated SECRET_KEYs that can be found publicly on GitHub alone suggests to me that no, the existence of that page is not sufficient to protect users from making this mistake.

Deploying to production already requires worrying about things more complicated than a SECRET_KEY, like having a database that actually durably persists your data (yes, SQLite does this in some deployment environments, but in many popular ones it doesn't). And if your Django site is accessible to the public internet, and its SECRET_KEY is compromised, then so is the site itself. So I'm not convinced that making it easier for users to quickly get a vulnerable site up and running on the public internet is in their interest.

Local development is, of course, a different story. Have we considered letting Django run with a blank SECRET_KEY in local scenarios? I guess DEBUG = True might be an okay way to handle that, though I can't help but wonder if there's a better alternative for making doing the safe thing the path of least resistance. We certainly don't want to push users to enable DEBUG in production...

Taymon

Reply all
Reply to author
Forward
0 new messages