Skip to content

Fix/regex non deterministic validation#593

Merged
antoatta85 merged 5 commits intomasterfrom
fix/regex-non-deterministic-validation
Apr 9, 2026
Merged

Fix/regex non deterministic validation#593
antoatta85 merged 5 commits intomasterfrom
fix/regex-non-deterministic-validation

Conversation

@antoatta85
Copy link
Copy Markdown
Collaborator

fix: reset RegExp lastIndex before claim validation to prevent non-deterministic verification

Vulnerability

RegExp.prototype.test() is stateful when the /g or /y flags are set — each call mutates lastIndex on the same object. ensureStringClaimMatcher() in src/verifier.js returned RegExp objects directly, and validateClaimValues() called .test() on them repeatedly without resetting lastIndex. This caused every second verification call to fail for perfectly valid tokens, producing an alternating PASS/FAIL pattern across all allowed* claim options (allowedAud, allowedIss, allowedSub, allowedJti, allowedNonce).

The result is a logical denial-of-service: ~50% of valid authentication requests are rejected when any allowed* option uses a RegExp with /g or /y.

Fix

In ensureStringClaimMatcher() (src/verifier.js), RegExp instances are now wrapped in a closure that resets lastIndex = 0 before each .test() call:

if (r instanceof RegExp) {
  return { test: v => { r.lastIndex = 0; return r.test(v) } }
}

Custom matcher objects (anything else with a .test method) and string-based matchers are unaffected.

Tests added (test/verifier.spec.js)

  • stateful RegExp /g flag must not cause non-deterministic claim validation - allowedAud
  • stateful RegExp /y flag must not cause non-deterministic claim validation - allowedAud
  • stateful RegExp /g flag must not cause non-deterministic claim validation - allowedIss
  • stateful RegExp /g flag must not cause non-deterministic claim validation - allowedSub
  • stateful RegExp /g flag must not cause non-deterministic claim validation - allowedJti
  • stateful RegExp /g flag must not cause non-deterministic claim validation - allowedNonce

Each test verifies that 8 consecutive calls with the same valid token all succeed when a stateful RegExp is used in the corresponding allowed* option.

FIXES #592

@martin-badin
Copy link
Copy Markdown

@antoatta85 Could you fix this build?

@antoatta85 antoatta85 merged commit 18d2590 into master Apr 9, 2026
7 checks passed
@antoatta85 antoatta85 deleted the fix/regex-non-deterministic-validation branch April 9, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Address Sec Adv: regex non deterministic validation

3 participants