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 .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
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.
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.
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.
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
References
External resources and documentation
Similar Rules
Explore related security rules for Python
JWT Hardcoded Secret
Finds jwt.encode() calls where the signing secret is a hardcoded string instead of a runtime configuration value.
JWT User Input in Payload
Traces user-controlled input from Flask/Django request parameters into jwt.encode() payloads using taint analysis.
Flask SQL Injection via Tainted String
Finds user input reaching raw SQL queries in Flask apps where parameterized queries should be used instead.
Frequently Asked Questions
Common questions about JWT Exposed Credentials
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.