Repository navigation
fix(security): fail closed on default/weak SECRET_KEY and stop shipping .env - #2513
Closed
failsafesecurity wants to merge 2 commits into
Closed
failsafesecurity wants to merge 2 commits into
failsafesecurity wants to merge 2 commits into
Conversation
…ng .env The template shipped FASTAPI_ENV=development together with SECRET_KEY=changethis, and the placeholder check only warned in development. Because the same HS256 key signs and verifies access tokens and password-reset tokens, a shipped default key let anyone forge a JWT for any user, including the built-in superuser (CWE-321, CVSS 9.3). - Make _check_default_secret raise unconditionally (all environments); remove the development warning path so the app refuses to start on a placeholder secret. - Enforce a minimum SECRET_KEY length (32 chars). - Stop tracking .env and add it to .gitignore/.dockerignore; add .env.example. - Add scripts/generate-env.sh to generate strong random secrets for local dev/CI. - Wire the generator into the backend, docker-compose, and playwright workflows. - Update development.md and add a fail-closed config regression test.
Contributor
|
This was marked as potentially AI generated and will be closed now. If this is an error, please provide additional details, make sure to read the docs about contributing and AI. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the shipped-default-secret vulnerability that allows forgery of any JWT (including superuser password-reset tokens).
Finding: Shipped default
SECRET_KEYwith fail-open validation permits forgery of any JWT, including password-reset tokens for the superuserSeverity: CRITICAL — CVSS 4.0: 9.3
AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:NCWE: CWE-321 · OWASP: A04:2025 Cryptographic Failures
Scan ID:
cmv17pczu00womo01ei5nap4f(projectcmv17pcvt00wmmo010afycocp)Root cause
backend/app/core/config.py::_check_default_secretonly raised forSECRET_KEY == "changethis"whenFASTAPI_ENV != "development"; in development it merely warned. The repository shipped.envwithFASTAPI_ENV=developmentandSECRET_KEY=changethis, andcompose.override.ymlforcesFASTAPI_ENV: "development". The same HS256 key signs both access tokens (backend/app/core/security.py) and password-reset tokens (backend/app/utils.py), andbackend/app/core/db.pycreates the built-in superuser from shipped defaults — so anyone who copies the public template can mint a token for any user id/email and take over the superuser.PoC summary
docker compose up→ backend loadsSECRET_KEY=changethiswithFASTAPI_ENV=development.python3 -c 'import jwt,time; print(jwt.encode({"exp":time.time()+3600,"nbf":time.time(),"sub":"admin@example.com"},"changethis",algorithm="HS256"))'POST /api/v1/reset-password/with the forged token and a new password →200 Password updated successfully.admin@example.com, call a superuser-only endpoint (e.g.GET /api/v1/users/) → full admin access.Fix explanation
_check_default_secretnow raises unconditionally; the development warning path is removed, so the app refuses to start on a placeholder secret in every environment.SECRET_KEYshorter than 32 characters (MINIMUM_SECRET_KEY_LENGTH)..envis removed from version control and added to.gitignoreand.dockerignore;.env.exampledocuments every variable with empty placeholders.scripts/generate-env.shgenerates strong randomSECRET_KEY,FIRST_SUPERUSER_PASSWORD, andPOSTGRES_PASSWORDvalues; it is wired into the backend, docker-compose, and playwright CI workflows so CI still boots.backend/tests/test_config_security.pyasserts placeholders and short keys are rejected in every environment.development.md) updated to describe the untracked.envand the generator.Notes
This is a defensive hardening change and does not change application behavior when a properly generated secret is configured. The companion test PR exercises these checks in CI.