Skip to content

[Vulnerability] Hardcoded JWT Secret May Lead to Privilege Escalation Risks #211

Description

@lx915

Description:

This project is an open source project, and any user can access the hard coded JWT Secret in this project. At the same time, there are no warning prompts when starting the project using the default JWT Secret value, so most users may not modify this JWT Secret default value, which may allow attackers to forge arbitrary user permission tokens, thereby bypassing authentication and authorization mechanisms and accessing protected interfaces.

Key Location:

"secret_key": "super_secret"

Vulnerability Type:

Type Description
CWE-798 Use of Hard-coded Credentials
CWE-321 Use of Hard-coded Cryptographic Key

Severity:

High/Critical

Exploitability Analysis:

The project defines the default JWT Secret as super_secret in cookiecutter.json. After the project template is rendered, this value is written into backend/app/core/security.py:10 as SECRET_KEY, and eventually flows into the JWT validation logic in backend/app/core/auth.py:19.

Secret Flow

Stage Location Description
Default Secret Definition cookiecutter.json:10 The default JWT Secret is super_secret.
Template Rendering Output backend/app/core/security.py:10 The default value is rendered as SECRET_KEY.
Token Verification backend/app/core/auth.py:19 SECRET_KEY is used to verify JWT signatures.

JWT Payload Analysis

The production JWT payload contains the following fields:

Claim Meaning Security Analysis
sub User email A persistent identity identifier that can be obtained through registration, enumeration, or social engineering.
permissions Permission string, such as admin or user The permission value may be observable or guessable, although superuser checks mainly rely on database fields.
exp Expiration time A time-based claim that can be set by an attacker when forging a token.

The payload does not contain any server-generated high-entropy value that is enforced during validation, nor is it bound to server-side session state, jti, nonce, or token versioning.

Token Validation Flow

The request validation flow is as follows:

  1. The server extracts the JWT from the HTTP Authorization: Bearer header;
  2. It calls jwt.decode to verify the signature using SECRET_KEY;
  3. After signature verification succeeds, the server extracts email and permissions from the payload;
  4. The server queries the database by email to check whether the user exists;
  5. If the user exists, the corresponding user object is returned;
  6. The global get_current_active_user dependency for /api/v1 routes relies on this identity result;
  7. Downstream business logic uses this authenticated identity to access protected endpoints.

This is a semi-stateful token model. Although the server queries the database to verify whether the email corresponds to an existing user, the email itself is a persistent identifier that can be obtained or enumerated by an attacker. Therefore, this database lookup does not effectively prevent user impersonation once the hardcoded secret is known.

Business Impact

get_current_user relies on the sub claim in the JWT payload as the user identity. In auth.py:29, token_data.email is used to query the database user. All /api/v1 routes protected by the global authentication dependency rely on this identity result for access control.

Although get_current_active_superuser checks the database-backed is_superuser field instead of directly trusting the permissions claim in the token, an attacker can still forge a JWT for any known user email, bypass login authentication, and impersonate that user to access protected endpoints. If the target email belongs to an administrator, the attacker may further obtain privileged access.

Once an attacker obtains the default hardcoded secret super_secret, they can craft a JWT containing any known user email and a valid expiration time. After the forged token passes signature verification and the user existence check, the server treats the attacker as that user, resulting in user impersonation, authentication bypass, and unauthorized access.

Impact:

-Attackers can forge any user's JWT
-Can impersonate administrators or high privilege accounts to access sensitive interfaces
-The user identity authentication mechanism has failed
-May lead to data leakage, unauthorized operations, or account takeover

Fix:

JWT Secret can be placed in the system environment variable or disabled from starting projects with default values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions