Repository navigation
Hard-Coded Django SECRET_KEY Fallback Reaches Production #2502
Description
Hard-Coded Django SECRET_KEY Fallback Reaches Production
Conclusion
backend/config/settings/base.py accepts a public hard-coded fallback for SECRET_KEY. production.py imports the complete base configuration, and the Docker image sets another public placeholder. A deployment that does not override the environment therefore runs with a known Django secret.
The current code does expose Django’s password-reset endpoints, but knowing SECRET_KEY alone is not enough to create a valid reset token for an arbitrary victim. Django binds the token to the target user’s password hash, last_login, email, primary key, and timestamp. I found no anonymous path in Doccano that discloses the required password hash or equivalent server-side state.
Therefore, this is a confirmed hard-coded-secret/security-configuration defect (CWE-321)
Affected code and default values
The fallback in base.py is:
SECRET_KEY = env("SECRET_KEY", "v8sk33sy82!uw3ty=!jjv5vp7=s2phrzw(m(hrn^f7e_#1h2al")
The production settings import it without replacing or validating it:
from .base import *The Docker image also embeds a public production placeholder:
ENV SECRET_KEY="change-me-in-production"The production Compose service selects config.settings.production but does not define SECRET_KEY, so the image-level placeholder is inherited:
docker-compose.prod.yml#L10-L19
The project documentation itself tells operators to replace the fixed default, but the application does not fail closed when they do not:
Impact
The hard-coded key compromises the secrecy of any Django signing feature that relies on it. The impact becomes an authentication issue if Doccano or a deployment uses the key for a signed-cookie session backend, another secret-only authentication artifact, or a reset-token implementation that does not bind tokens to server-side user state.
Remediation
- Remove both hard-coded values and require
SECRET_KEYto be supplied by the deployment environment or a secret manager. - Fail startup when the variable is missing, too short, or equal to a known placeholder.
- Rotate the exposed values in every deployment. Invalidate sessions and reset tokens issued under the old key; do not retain the public key indefinitely as a fallback.
- Add a deployment test that verifies production cannot start with the repository or Docker defaults.
- Keep password-reset tokens bound to user state and verify that any future signed authentication artifact uses an independent, high-entropy secret.
Historical disclosure and duplicate check
The repository’s public Security page reports that no SECURITY.md policy is configured, and the public Security Advisories page reports no published repository advisories.
I reviewed public Issues, Pull Requests, exact-secret searches, and searches for SECRET_KEY, password-reset tokens, and authentication bypasses. I found no exact prior report of this root cause. The following are related but not duplicates:
- Issue #748 discusses making default admin credentials configurable and warns that guessed defaults are unsafe; it does not report the Django
SECRET_KEYpath. - Issue #1158 contains a Docker build log showing
SECRET_KEY="change-me-in-production"; it is a deployment/build issue, not a security report for password-reset forgery. - CVE-2024-40441 concerns a distinct Doccano privilege-escalation issue involving
model_attribsand is not a duplicate.
This public-history check cannot exclude an undisclosed private report.
Related works
These cases are relevant references for hard-coded secrets and secret-backed authentication failures:
- Arcade MCP — CVE-2025-66454
- Bambuddy — CVE-2026-25505
- AstrBot — CVE-2025-55449
- Apache Superset — CVE-2023-27524
- Label Studio — CVE-2023-43791
- Redash — CVE-2021-41192
- PPress — CVE-2025-54761
- WeRSS — CVE-2026-2215
This report is part of my ongoing security research. If you have any questions or would like clarification, please feel free to @mention me at any time. I would be genuinely pleased to contribute, even in a small way, to improving Doccano’s security.
Activity