# Boolean logic errors in token validation

Checks joined by wrong AND/OR, missing return after failed check, or token compared to self-minted value

_Area: Web authentication and account takeover. Seen in 3 disclosed reports; latest 2026-07-22. Updated 2026-10-31._

## How it works
Token validation is a set of independent rejection conditions: signature valid, issuer/audience correct, not expired, bound to this client, fresh. Each must be able to reject on its own. The assumption that breaks is that the code actually enforces each condition. Three shapes: (1) conditions joined by the wrong boolean operator, so rejection requires several failures at once and any single failure passes; (2) a failed check that logs or throws but does not abort, so execution falls through to the success path; (3) the presented credential is never verified against its issuer at all — the server mints its own token and compares strings, so anything it can mint for itself matches.

## Where it shows up
- Boolean expressions joining client-binding, expiry, audience or issuer checks with `&&`/`||` [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qh6q-598w-w6m2.md)
- A freshness, signature or revocation branch that logs or raises but has no `return`/abort before emitting success [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-g7hg-vrcf-mvmr.md)
- An inbound authenticator that reuses an outbound credential object and compares strings instead of verifying the JWT against tenant JWKS [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md)
- Validation scope or expected value derived from client-supplied input (e.g. a Host header) [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md)
- Optional replay defenses (nonce) disabled by default, leaving freshness as the only guard [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-g7hg-vrcf-mvmr.md)

## How to review
For each rejection condition, ask: can this condition alone stop the flow? Trace the exact path from check to success event and confirm a failed check reaches an abort (return, throw, or explicit reject) before any token, session or VALID result is produced. For boolean joins, enumerate the truth table: a code must be rejected if the client mismatches OR it is expired, not only when both hold [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qh6q-598w-w6m2.md). For inbound auth, confirm the presented token's signature, issuer, audience and expiry are verified against the issuer's keys — never against a value the server itself minted [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md). Treat any client-controlled input used to scope validation as untrusted [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md).

## Variants seen
- Wrong operator (`&&` for `||`) merging independent rejection conditions [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qh6q-598w-w6m2.md)
- Missing return after a failed freshness check, success event still fires [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-g7hg-vrcf-mvmr.md)
- Self-minted token compared by string equality instead of JWT verification [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md)
- Validation scope taken from client-supplied header [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md)

## Why fixes fail
In E2 the freshness failure was detected and an exception raised, but without a return the flow continued — detection without abort is not a fix. Nonce validation remaining off by default means freshness is the sole defense, so any gap there is exploitable.

## Impact and severity
Authentication bypass: cross-client token exchange [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-qh6q-598w-w6m2.md), replay of stale revocation responses [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-g7hg-vrcf-mvmr.md), and unauthenticated access to OTLP receivers [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md). Severity is high because a single logic slip defeats the entire boundary; it worsens when the failed check is only logged, when replay defenses are optional, and when the expected value is attacker-influenced.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-pjv4-3c63-699f.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-g7hg-vrcf-mvmr.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-qh6q-598w-w6m2.md
