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:
- The server extracts the JWT from the HTTP
Authorization: Bearer header;
- It calls
jwt.decode to verify the signature using SECRET_KEY;
- After signature verification succeeds, the server extracts
email and permissions from the payload;
- The server queries the database by
email to check whether the user exists;
- If the user exists, the corresponding user object is returned;
- The global
get_current_active_user dependency for /api/v1 routes relies on this identity result;
- 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.
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:
fastapi-react/cookiecutter.json
Line 10 in af17f2d
Vulnerability Type:
Severity:
High/Critical
Exploitability Analysis:
The project defines the default JWT Secret as
super_secretincookiecutter.json. After the project template is rendered, this value is written intobackend/app/core/security.py:10asSECRET_KEY, and eventually flows into the JWT validation logic inbackend/app/core/auth.py:19.Secret Flow
cookiecutter.json:10super_secret.backend/app/core/security.py:10SECRET_KEY.backend/app/core/auth.py:19SECRET_KEYis used to verify JWT signatures.JWT Payload Analysis
The production JWT payload contains the following fields:
subpermissionsadminoruserexpThe 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:
Authorization: Bearerheader;jwt.decodeto verify the signature usingSECRET_KEY;emailandpermissionsfrom the payload;emailto check whether the user exists;get_current_active_userdependency for/api/v1routes relies on this identity result;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_userrelies on thesubclaim in the JWT payload as the user identity. Inauth.py:29,token_data.emailis used to query the database user. All/api/v1routes protected by the global authentication dependency rely on this identity result for access control.Although
get_current_active_superuserchecks the database-backedis_superuserfield instead of directly trusting thepermissionsclaim 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.