﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
33526	Accept truthy/falsy values in security checks.	Will H	nobody	"When running {{{python manage.py check --deploy}}}, deployment security checks are performed on the following settings values:

SECURE_SSL_REDIRECT
SECURE_HSTS_SECONDS
SECURE_HSTS_INCLUDE_SUBDOMAINS
SECURE_HSTS_PRELOAD
SESSION_COOKIE_SECURE
CSRF_COOKIE_SECURE

For those who use separate modules for dev/prod they can simply hardcore these settings as booleans. If you use environment variables, truthy and falsy values are more convenient. Otherwise, you have to write a helper function to convert the environment variable strings to booleans.

For example, I use the {{{dotenv}}} Python package to read environment variables in as strings 1 or 0 from a {{{.env}}} file, then use {{{int()}}} to convert them inline to truthy or falsy integer values:

{{{
from dotenv import load_dotenv
load_dotenv()

SECURE_SSL_REDIRECT = int(os.environ.get(""DJANGO_SECURE_SSL_REDIRECT"", default=1))
}}}

It's been brought to my attention that many use {{{env.bool()}}} from the  {{{django-environ}}} package to achieve this. However, I believe truthy/falsy values should be supported as well to circumvent this requirement.

The issue: 3 of the above settings don't use truthy or falsy values for their checks in [https://github.com/django/django/blob/main/django/core/checks/security/base.py django.core.security.checks.base], while the rest do.

On lines 178, 188 and 203 the checks for SECURE_HSTS_INCLUDE_SUBDOMAINS, SECURE_HSTS_PRELOAD and SECURE_SSL_REDIRECT respectively use {{{is True}}}.

On the other hand, [https://github.com/django/django/blob/main/django/core/checks/security/csrf.py django.core.security.checks.csrf] on line 40 and [https://github.com/django/django/blob/main/django/core/checks/security/sessions.py django.core.security.checks.sessions] on line 69 both use truthy/falsy checks.

This causes the following scenario for a setting using {{{is True}}}:

{{{SECURE_SSL_REDIRECT = True}}} <-- Passes checks
{{{SECURE_SSL_REDIRECT = 1}}} <-- Does not pass checks

For a setting that uses truthy/falsy checks:

{{{SESSION_COOKIE_SECURE = True}}} <-- Passes checks
{{{SESSION_COOKIE_SECURE = 1}}} <-- Passes checks

To reproduce this, simply hardcode the settings above using truthy/falsy values, run the checks, and the 3 settings mentioned above will fail deployment checks.

I currently get around this limitation by reading in TRUE as a string from a .env file and converting it to a boolean with a helper function:

{{{
def env_to_bool(value):
    if isinstance(value, bool):
        return value
    else:
        return value.upper() == ""TRUE""

SECURE_SSL_REDIRECT = env_to_bool(os.environ.get(""DJANGO_SECURE_SSL_REDIRECT"", default=True))
}}}

I couldn't find a valid reason for not using truthy/falsy checks for the three settings that don't pass checks without a boolean True. I would be happy to take this on as my first contribution but wanted to open a bug ticket first to see if I'm missing a reason these use {{{is True}}} while the other checks don't.

If anything, the checks should all use a consistent convention so as to not inconvenience those who are attempting to run checks with truthy/falsy settings values.

If more information is needed please let me know."	Cleanup/optimization	closed	Core (System checks)	4.0	Normal	wontfix			Unreviewed	0	0	0	0	1	0
