JWT Exposed Credentials

MEDIUM

Detects jwt.encode() calls where passwords or secrets may be included in the token payload, exposing them to anyone who reads the token.

Rule Information

Language
Python
Category
JWT
Author
Shivasurya
Shivasurya
Last Updated
2026-03-22
Tags
pythonjwtpyjwtcredentialspassword-exposuredata-exposurecleartextauditCWE-522CWE-312OWASP-A02OWASP-A04
CWE References

Interactive Playground

Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.

pathfinder scan --ruleset python/PYTHON-JWT-SEC-004 --project .
1
2
3
4
5
6
7
8
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

About This Rule

Understanding the vulnerability and how it is detected

This rule flags jwt.encode() calls for review to ensure that passwords, API keys, or other secrets aren't being included in the JWT payload. JWT payloads are base64-encoded, not encrypted. Anyone who intercepts the token -- from browser DevTools, a proxy, server logs, or a database -- can decode the payload and read every field in plaintext.

Developers sometimes include passwords in JWT payloads because it seems convenient -- "the token is signed, so it's secure." Signing prevents tampering, not reading. A signed JWT is like a sealed letter written in pencil: nobody can change it, but anyone can read it.

The rule operates at audit level, flagging all jwt.encode() calls. This is because the engine can't yet inspect dictionary keys in arguments to check specifically for keys like "password", "secret", or "api_key". Future engine updates will add dict key matching to reduce false positives.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Password Exposure

If a password is in the JWT payload, anyone who gets the token can read it. JWTs appear in Authorization headers (visible in browser DevTools), server access logs, reverse proxy logs, and error tracking tools. That's a lot of places for a plaintext password to end up.

2

Credential Harvesting

Tokens are stored in localStorage, cookies, and mobile app storage. A single XSS vulnerability or compromised device can expose every JWT the user has received -- and if those tokens contain passwords, the attacker gets credentials for free.

3

Compliance Violations

Storing passwords in cleartext (even base64-encoded) violates PCI DSS, GDPR, and most security standards. Base64 is not encryption -- it's encoding. Auditors and pen testers will flag this immediately.

4

Password Reuse Exploitation

Users reuse passwords across services. A password leaked from a JWT can be used in credential stuffing attacks against other services -- email, banking, cloud accounts.

How to Fix

Recommended remediation steps

  • 1Never put passwords, API keys, secrets, or PII in JWT payloads -- use opaque user IDs and look up sensitive data server-side
  • 2If you need to include user attributes in the token, limit it to non-sensitive claims like user_id, role, and permissions
  • 3Use JWE (JSON Web Encryption) if you genuinely need encrypted token payloads, but consider whether the data should be in the token at all
  • 4Review your JWT payload structure with your security team -- the principle is minimum necessary claims
  • 5Add automated checks in code review to catch sensitive keys being added to token payloads

Detection Scope

How Code Pathfinder analyzes your code for this vulnerability

This rule matches all jwt.encode() calls resolved through the PyJWT library using QueryType-based type inference. It currently operates as an audit rule that flags all jwt.encode() calls for review. The rule cannot yet inspect dictionary keys in the payload argument to specifically flag keys like "password", "secret", or "api_key" -- this requires dict key matching support in the engine.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

OWASP Top 10
A02:2021 - Cryptographic Failures
PCI DSS v4.0
Requirement 3.4 -- render PAN unreadable anywhere it is stored
GDPR
Article 32 -- appropriate technical measures to protect personal data
NIST SP 800-53
SC-28: Protection of Information at Rest
SOC 2
CC6.7 -- restrict transmission of sensitive data

References

External resources and documentation

Similar Rules

Explore related security rules for Python

Frequently Asked Questions

Common questions about JWT Exposed Credentials

Base64 is a reversible encoding scheme -- anyone can decode it without any key. Run echo "eyJ1c2VyIjoiYWRtaW4ifQ" | base64 -d and you get {"user":"admin"}. Encryption requires a secret key to decrypt. JWT payloads are base64-encoded, which means they are readable by anyone who has the token.
Include only non-sensitive identifiers and authorization claims: user_id (opaque, not email), role, permissions, exp (expiration), iat (issued at), iss (issuer). Look up anything sensitive server-side using the user_id from the token.
The engine can't yet inspect dictionary keys in function arguments. To check specifically for keys like "password" or "secret" in the payload dict, it would need dict key matching support. This is a known engine limitation tracked in the product roadmap. For now, the rule flags all jwt.encode() calls for manual review.
JWE (JSON Web Encryption) encrypts the payload, so it can't be read without the decryption key. But first ask whether the data needs to be in the token at all. Tokens get stored in browsers, logged by proxies, and cached by CDNs. Even encrypted, minimizing the data in a token reduces your attack surface.
Run: pathfinder ci --ruleset python/jwt --project . It outputs SARIF, JSON, or CSV. On GitHub, it posts inline review comments directly on pull requests pointing to the exact lines. No dashboard needed.
SEC-004 is about credentials in the payload (passwords, API keys). SEC-005 is about user-controlled input flowing into jwt.encode() through taint analysis -- it catches cases where request data (form fields, query parameters) ends up in the token payload, which could expose user-submitted sensitive data.

New feature

Get these findings posted directly on your GitHub pull requests

The JWT Exposed Credentials rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works