Type Confusion with Bearer Tokens
How Type Confusion Manifests in Bearer Tokens
Type confusion in Bearer Tokens occurs when a system incorrectly interprets or validates token types, leading to authentication bypasses or privilege escalation. This vulnerability is particularly dangerous in Bearer Tokens because the "Bearer" prefix is often treated as a simple string rather than a strict token type identifier.
Consider this common implementation pattern:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
The server extracts the token by splitting on spaces:
const authHeader = req.headers.authorization;
if (authHeader.startsWith('Bearer ')) {
const token = authHeader.substring(7);
// Process token
}
Type confusion can occur when:
- The server accepts multiple token types but doesn't properly validate the prefix
- Case sensitivity issues allow "bearer" vs "Bearer" bypasses
- Whitespace variations like "Bearer " or "Bearer " are mishandled
- Additional prefixes like "Bearer+" or "Bearer-" are incorrectly processed
A real-world example from CVE-2022-27255 in Auth0's SDK demonstrated how type confusion allowed attackers to bypass authentication by sending tokens with unexpected prefixes that the library didn't properly reject.
Here's a vulnerable implementation:
// VULNERABLE: Type confusion via prefix manipulation
function verifyBearerToken(authHeader) {
if (authHeader && authHeader.toLowerCase().includes('bearer')) {
const token = authHeader.replace(/bearer/gi, '').trim();
// Process token without validating it's actually a Bearer token
return verifyJwt(token);
}
return null;
}
// Attack: "Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
// The function strips "Basic" and processes the JWT as if it were Bearer
Another manifestation occurs when token validation logic assumes the prefix format without proper parsing:
// VULNERABLE: Assumes strict "Bearer " prefix
function parseBearerToken(authHeader) {
if (authHeader.startsWith('Bearer ')) {
return authHeader.substring(7); // Works fine
}
// Missing else case - returns undefined but doesn't reject
return authHeader;
}
// Attack: "Bearer" (no space) returns the full string "Bearer" instead of null
// This might be processed as a valid token by downstream logicBearer Tokens-Specific Detection
Detecting type confusion in Bearer Tokens requires systematic testing of prefix handling and validation logic. The most effective approach combines automated scanning with manual testing.
Automated detection with middleBrick identifies type confusion by:
- Testing multiple prefix variations: "Bearer", "bearer", "BEARER", "Bearer ", "Bearer "
- Attempting authentication with non-Bearer prefixes like "Basic", "Digest", "Mac", "Token"
- Testing malformed tokens that combine prefixes with valid JWTs
- Verifying that authentication fails when the prefix is missing or incorrect
middleBrick's Bearer Tokens-specific scanning includes:
$ middlebrick scan https://api.example.com/auth
=== Bearer Token Type Confusion Test ===
✓ Standard Bearer prefix validation
✓ Case sensitivity testing (bearer vs Bearer)
✓ Whitespace handling (Bearer , Bearer
)
✗ Prefix stripping vulnerability detected
Severity: High
Path: /api/protected
Issue: Authentication bypass via Basic prefix manipulation
Remediation: Implement strict prefix validation
Manual testing techniques for Bearer Token type confusion:
# Test case sensitivity
Authorization: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# Test whitespace variations
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# Test prefix confusion
Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Digest eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Bearer+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Code review patterns to identify type confusion risks:
// Look for these anti-patterns:
if (authHeader.includes('Bearer')) { ... } // Case-sensitive issue
if (authHeader.toLowerCase().includes('bearer')) { ... } // Strips all 'bearer' instances
if (authHeader.match(/bearer/i)) { ... } // Regex may not validate format
if (authHeader.split(' ')[0] === 'Bearer') { ... } // Doesn't handle missing space
Bearer Tokens-Specific Remediation
Remediating type confusion in Bearer Tokens requires strict validation of both the prefix format and the token structure. The key is to implement defensive parsing that rejects any deviation from the expected format.
Secure Bearer Token validation pattern:
function validateBearerToken(authHeader) {
if (!authHeader || typeof authHeader !== 'string') {
return { valid: false, error: 'Missing authorization header' };
}
// Strict prefix validation - must be exactly "Bearer "
if (!authHeader.startsWith('Bearer ')) {
return { valid: false, error: 'Invalid token type - must be Bearer' };
}
// Extract token - exactly 7 characters for "Bearer "
const token = authHeader.substring(7);
// Validate token structure (JWT format as example)
if (!token.match(/^[A-Za-z0-9-_]+.[A-Za-z0-9-_]+.[A-Za-z0-9-_]+$/)) {
return { valid: false, error: 'Invalid token format' };
}
// Verify the token signature and claims
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
return { valid: true, token: decoded };
} catch (err) {
return { valid: false, error: 'Invalid token signature' };
}
}
// Usage
const authResult = validateBearerToken(req.headers.authorization);
if (!authResult.valid) {
return res.status(401).json({ error: authResult.error });
}
Framework-specific implementations:
// Express middleware with strict Bearer validation
const express = require('express');
const jwt = require('jsonwebtoken');
function bearerTokenMiddleware(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Bearer token required' });
}
const token = authHeader.substring(7);
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (err) {
return res.status(401).json({ error: 'Invalid token' });
}
}
// FastAPI implementation
from fastapi import HTTPException, Request
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
from jose import jwt
async def bearer_token_middleware(request: Request, call_next):
auth_header = request.headers.get('authorization')
if not auth_header or not auth_header.startswith('Bearer '):
raise HTTPException(status_code=401, detail='Bearer token required')
token = auth_header[7:]
try:
payload = jwt.decode(token, settings.JWT_SECRET, algorithms=['HS256'])
request.state.user = payload
except jwt.JWTError:
raise HTTPException(status_code=401, detail='Invalid token')
return await call_next(request)
Additional security measures:
// Reject tokens with unexpected characters
function validateTokenFormat(token) {
// JWT format: header.payload.signature
const parts = token.split('.');
if (parts.length !== 3) return false;
// Each part should be base64url encoded
return parts.every(part =>
/^[A-Za-z0-9-_]+$/.test(part.replace(/=+$/, ''))
);
}
// Implement timing-safe comparisons
function timingSafeCompare(a, b) {
if (a.length !== b.length) return false;
let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
}
return result === 0;
}
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |