# JWT kid parameter allows SQL injection when used to fetch public key from database

- **ID:** `security/jwt-kid-parameter-sql-injection`
- **Domain:** security
- **Category:** data_error
- **Verification:** ai_generated
- **Fix Rate:** 90%

## Root Cause

The JWT header's kid (key ID) parameter is directly concatenated into a SQL query to fetch the verification key, enabling SQL injection if the kid value is maliciously crafted.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| jsonwebtoken 9.0.0 | active | — | — |
| PyJWT 2.8.0 | active | — | — |
| jjwt 0.12.3 | active | — | — |
| Spring Security 6.2.0 | active | — | — |

## Workarounds

1. **Use parameterized queries (prepared statements) for fetching the public key. Example in Python with psycopg2: cursor.execute('SELECT key FROM keys WHERE kid = %s', (jwt_header['kid'],))** (98% success)
   ```
   Use parameterized queries (prepared statements) for fetching the public key. Example in Python with psycopg2: cursor.execute('SELECT key FROM keys WHERE kid = %s', (jwt_header['kid'],))
   ```
2. **Validate kid against a whitelist of allowed key IDs before using it in any query.** (85% success)
   ```
   Validate kid against a whitelist of allowed key IDs before using it in any query.
   ```

## Dead Ends

- **Validating kid format with regex but still using string concatenation in SQL** — Regex validation can be bypassed (e.g., with encoded characters); the fundamental issue is parameterized queries not used. (70% fail)
- **Escaping the kid value manually with backslashes or quotes** — Escaping is error-prone and database-specific; a crafted input can still break out of the string context. (90% fail)
