Opened 6 weeks ago

Closed 6 weeks ago

#35901 closed New feature (wontfix)

settings.DEBUG could reject non-empty string values (or in particular "off", "no", "0", "disabled", "false", "False")

Reported by: Sebastian Pipping Owned by:
Component: Core (Other) Version: dev
Severity: Normal Keywords: typed settings
Cc: Sebastian Pipping, Venkatesh S Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hi!

I came across a setup recently where (simplified) troubling code DEBUG = os.environ.get("DEBUG", False) with environment variables state DEBUG=0 (and later DEBUG=False) was activating Debug mode (while not intended to and and unaware of) in practice because these (and all other non-empty) strings evaluate to True in Python:

In [1]: bool("")
Out[1]: False

In [2]: bool("False")
Out[2]: True

In [3]: bool("0")
Out[3]: True

The related code is Open Source and my related pull request for their project is public at https://github.com/climateconnect/climateconnect/pull/1331 .

To cheaply protect users from accidents like these (that can easily result in arbitrary remote code execution) in the future, Django could reject values from settings.DEBUG that are (a) any string or (b) any non-empty string or (c) in a list of known excluded words (e.g. "off", "no", "0", "disabled", "false", "False").

What do you think?

Change History (8)

comment:1 by Venkatesh S, 6 weeks ago

Thank you, Sebastian, for reporting this and for your detailed explanation!

Our setup is handled this differently. However, I now see that, like many projects, it could indeed be affected by unintended string evaluations if values are drawn directly from .env files without parsing.

In our current Django configuration, we set DEBUG as a Boolean directly rather than retrieving it from .env, which avoids this specific issue for us.

Thank you!

comment:2 by Venkatesh S, 6 weeks ago

Cc: Venkatesh S added
Resolution: invalid
Status: newclosed

comment:3 by Sebastian Pipping, 6 weeks ago

Resolution: invalid
Status: closednew

This is not about a specific setup but a pattern or I would not even create this ticket. Many users control debug mode through an environment variable and hopefully get this right like https://github.com/hartwork/jawanndenn/blob/356ee23f9b1bb3fa876e405a5b9fae0c0729e0df/jawanndenn/settings.py#L31 but reality proves that users could use help with this. Please re-consider just shutting me down. Thank you.

comment:4 by Sebastian Pipping, 6 weeks ago

Has patch: set

comment:5 by Tim Graham, 6 weeks ago

I'd be inclined to say wontfix unless a consensus can be reached on the forum. See a related thread. on a proposal to add a system check to verify the type of all settings. There are often unintended side effects when we've added checks like this.

Here is an interesting approach (though perhaps not the best one) I found to help avoid a configuration mistake with environment variables:

from ast import literal_eval
from os import getenv

DEBUG = literal_eval(getenv('DEBUG', 'False'))

comment:6 by Sebastian Pipping, 6 weeks ago

The code sample is a nice idea.

With regard to checking all setting types I don't see need to make the picture that big: the type check is an implemenation detail — we could as well just block values like `"off", "no", "0", "disabled", "false", "False" — but then the list will never be complete. The current explicit check also doesn't prevent any later migrations towards full blown type checks in the future. Why not start small?

I would appreciate to consider that this change alone would have saved unfortunate setup https://github.com/climateconnect/climateconnect/pull/1331 from potential remote code execution. That's the key motivator behind this suggestion: it could have been prevented easily.

comment:7 by Mariusz Felisiak, 6 weeks ago

Agreed with Tim. "wontfix" for me. This will definitely have side-effects on some projects.

comment:8 by Natalia Bidart, 6 weeks ago

Keywords: typed settings added; security debug removed
Resolution: wontfix
Status: newclosed
Type: UncategorizedNew feature

I agree with Tim and Mariusz that this proposal isn't suitable for Django (as a core feature). Moreover, I think it qualifies as a duplicate of #35231 (which is a ticket related to the forum link shared by Tim).

I'll close this as wontfix because, if we were to implement a change that only applies to DEBUG, it would be incomplete and inconsistent. Users would likely request similar handling for every boolean setting. Even if we made the behavior consistent, I don't believe this parsing logic belongs in the settings module. Django settings are meant to be Python files, and the core framework doesn't include functionality for reading from environment variables.

Another reason for closing as wontfix is that there are third-party packages that handle parsing from env variables effectively. For example, django-environ uses BOOLEAN_TRUE_STRINGS = ('true', 'on', 'ok', 'y', 'yes', '1') for bool logic parsing.

I think it's important to decouple the settings definition (the Python file where a string is not a bool) from reading settings from external sources, such as environment variables, INI config files, Puppetfiles, etc. The former definitely belongs to Django, while the latter is better suited for third-party packages or custom business logic.

Note: See TracTickets for help on using tickets.
Back to Top