HIGH privilege escalationbearer tokens

Privilege Escalation with Bearer Tokens

How Privilege Escalation Manifests in Bearer Tokens

Bearer tokens are commonly used to convey identity and authorization information in APIs. When the token is not properly validated, an attacker can craft or modify a token to gain higher privileges than intended. This type of privilege escalation often appears in the following patterns:

  • Token tampering with weak or missing signature verification: If an API accepts a JWT and only checks that the token is present (or verifies it with a weak secret), an attacker can flip the alg header to none or forge a signature using a guessed secret, then add claims such as role: admin or scope: write:all.
  • Insufficient claim validation: Even when a signature is validated, APIs sometimes ignore critical claims like exp (expiration), aud (audience), iss (issuer), or custom scope claims. An attacker can reuse an old token that still validates signature-wise but has expired, or present a token issued for a different service (audience mismatch) to escalate privileges.
  • KID header injection: Some libraries use the kid (key ID) field to look up the verification key. If the key lookup is based on user‑controlled input without proper validation, an attacker can point kid to a malicious key they control, thereby signing a token with elevated claims.
  • Token leakage and replay: Tokens logged in URLs, error messages, or stored insecurely can be captured and replayed. If the API does not enforce token binding (e.g., to a specific IP or client certificate), a stolen token can be used from another context to act with the victim’s privileges.

Real‑world examples include CVE‑2022‑23529 (JSON Web Token library accepting alg:none) and CVE‑2020‑15257 (JWT validation bypass via kid injection). Both allow an attacker to escalate from a low‑privilege user to administrative access by manipulating the Bearer token presented to the API.

Bearer Tokens-Specific Detection

middleBrick’s black‑box scanner includes a dedicated privilege‑escalation check that focuses on how Bearer tokens are handled. During the 5‑15 second scan it:

  • Sends requests with no Authorization header to baseline the endpoint.
  • Presents a series of crafted Bearer tokens:
    • A valid token (if one can be discovered from public docs) to confirm normal behavior.
    • A token with the alg header set to none and elevated claims (e.g., role: admin).
    • A token signed with a weak secret (brute‑forced common strings like secret, 123456).
    • A token with an expired exp claim but otherwise valid signature.
    • A token with a manipulated kid header pointing to an attacker‑controlled key URL.
    • A token with mismatched aud or iss claims.
  • Analyzes responses for changes in status code, returned data, or error messages that indicate the token was accepted and granted higher privilege (e.g., a 200 response with admin‑only data, or a change from 403 to 200).
  • Correlates findings with the OpenAPI/Swagger spec (when available) to verify that the endpoint expects specific scopes or roles.

Example of using the middleBrick CLI to test an API:

# Install the CLI (npm)
npm i -g middlebrick

# Scan a target endpoint
middlebrick scan https://api.example.com/orders

# Sample JSON output (truncated for clarity)
{
  "target": "https://api.example.com/orders",
  "score": 42,
  "grade": "F",
  "categories": [
    {
      "name": "Privilege Escalation",
      "severity": "high",
      "findings": [
        {
          "id": "PE-BT-001",
          "description": "Accepts JWT with alg:none and elevated role claim",
          "evidence": "Request with header Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJyb2xlIjoiYWRtaW4ifQ. returned 200 with admin order list",
          "remediation": "Verify JWT signature; reject tokens with alg:none"
        }
      ]
    }
  ]
}

If the scanner detects any of the above conditions, it flags a privilege‑escalation finding with severity ≥ medium, provides the exact request/response evidence, and links the issue to OWASP API Top 10 2023 A1: Broken Object Level Authorization (which includes vertical privilege escalation via token misuse).

Bearer Tokens-Specific Remediation

Fixing privilege‑escalation flaws in Bearer token usage requires proper validation of both the token’s integrity and its claims. Below are language‑agnostic principles followed by concrete code snippets for common stacks.

1. Verify the signature with a strong algorithm and key

Never accept unsigned tokens or rely on a secret that can be guessed. Use asymmetric keys (RS256, ES256) when possible, and if symmetric keys are used, ensure they are sufficiently long and random.

// Node.js – using jsonwebtoken with RS256
const jwt = require('jsonwebtoken');
const fs = require('fs');
const PUBLIC_KEY = fs.readFileSync('/etc/keys/public.pem', 'utf8');

function authenticate(req, res, next) {
  const auth = req.headers.authorization;
  if (!auth || !auth.startsWith('Bearer ')) {
    return res.status(401).send({error: 'Missing token'});
  }
  const token = auth.slice(7);
  try {
    const payload = jwt.verify(token, PUBLIC_KEY, { algorithms: ['RS256'] });
    // Attach payload to request for downstream use
    req.user = payload;
    next();
  } catch (err) {
    return res.status(401).send({error: 'Invalid token'});
  }
}

2. Validate essential claims

After signature verification, check exp, nbf, aud, iss, and any application‑specific scopes or roles.

// Continuing the Node.js example
function authenticate(req, res, next) {
  const auth = req.headers.authorization;
  if (!auth || !auth.startsWith('Bearer ')) {
    return res.status(401).send({error: 'Missing token'});
  }
  const token = auth.slice(7);
  try {
    const payload = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ['RS256'],
      audience: 'https://api.example.com/',
      issuer: 'https://auth.example.com/'
    });
    // Additional application checks
    if (!payload.scope || !payload.scope.includes('orders:read')) {
      return res.status(403).send({error: 'Insufficient scope'});
    }
    req.user = payload;
    next();
  } catch (err) {
    return res.status(401).send({error: 'Invalid or expired token'});
  }
}

3. Reject tokens with alg:none and verify KID handling

Explicitly refuse the none algorithm and ensure the kid field is resolved against a trusted key store, not used directly as a file path or URL.

// Python – using PyJWT with explicit algorithm list
import jwt
import os

PUBLIC_KEY = os.environ.get('JWT_PUBLIC_KEY')

def bearer_auth(token):
    try:
        # List of allowed algorithms; 'none' is omitted
        payload = jwt.decode(token, PUBLIC_KEY, algorithms=['RS256'],
                             audience='https://api.example.com/',
                             issuer='https://auth.example.com/')
        if 'orders:read' not in payload.get('scope', []):
            raise jwt.InvalidTokenError('Missing scope')
        return payload
    except jwt.PyJWTError as e:
        raise ValueError(f'Token validation failed: {e}')

# Usage in a Flask view
from flask import request, abort

@app.route('/api/orders')
def orders():
    auth = request.headers.get('Authorization', '')
    if not auth.startswith('Bearer '):
        abort(401)
    token = auth.split()[1]
    try:
        user = bearer_auth(token)
    except ValueError:
        abort(401)
    # proceed with user context
    return {'orders': get_orders_for(user['sub'])} 

4. Bind tokens to client context (optional but strong)

If feasible, include a hash of the client TLS certificate or a nonce in the token and verify it on each request. This mitigates replay attacks even if a token is stolen.

Applying these fixes eliminates the privilege‑escalation vectors that middleBrick’s scanner looks for, turning a failing grade (F) into a passing one (A‑C) for the Privilege Escalation category.

Frequently Asked Questions

Does middleBrick need any credentials or agents to test Bearer token privilege escalation?
No. middleBrick performs a completely unauthenticated, black‑box scan. You only provide the public API URL; the tool sends crafted Bearer tokens and analyzes responses without requiring any installation, agents, or credentials on the target system.
How does middleBrick differentiate a legitimate admin token from a forged one used for privilege escalation?
The scanner does not rely on knowing a legitimate token. It sends a series of deliberately malformed tokens (e.g., alg:none, weak secret, expired, wrong audience, manipulated kid) and checks whether the API accepts them and returns privileged data. Acceptance of any of these crafted tokens indicates a validation flaw, which is reported as a privilege‑escalation finding.