The Guardian library's revoke/3 function accepts tokens without signature verification, allowing attackers to revoke arbitrary user sessions with forged tokens. The critical detail the CVSS score buries: this wasn't an oversight born from ignorance. The codebase already contains decode_and_verify — it's used correctly in refresh/2 and exchange/4. The developers knew how to implement this; they simply didn't apply it to one state-mutating path.

This inconsistency is the real signal. When signature verification exists in sibling functions but not here, it suggests either a copy-paste gap during implementation or a dangerous internal assumption that revocation is 'read-only' and somehow safe without authentication. Neither is acceptable. Deleting a session from a whitelist is a state change, and this function was mutating state on unauthenticated input for six years (1.0.0 through 2.4.0).

What makes this worse: revocation attacks are invisible. An attacker forging a token to revoke a victim's session leaves no forensic footprint — it looks like legitimate logout. Your logs show a successful revocation; your monitoring sees intended behavior. The victim re-authenticates, gets revoked again, and may hit rate limits or lockout thresholds from their own defensive systems. This attack is self-perpetuating through the victim's own protections, and most security stacks won't alert on it.

For defenders: patch by adding decode_and_verify before the revoke operation. But the discovery should trigger deeper questions. What other state-mutating functions in your authentication flow bypass checks that exist elsewhere? Have you been relying on environmental controls (network restrictions, input validation) that the library's contract doesn't guarantee? The pattern of 'optimization skips authentication' has appeared across OAuth and session libraries for a decade — this CVE is one data point in that lineage, and the fix is trivial, but the architectural inconsistency that allowed it to persist suggests your library's security properties may not have been stress-tested against adversarial input.

Audit the call graph. Verify every function that mutates state enforces signature verification first. Assume the library's defaults protect less than you thought.