Skip to content

fix(sdk): clear SonarQube ReDoS hotspot in base64url encode#62

Merged
wolpert merged 1 commit into
mainfrom
fix-base64url-redos-hotspot
Jun 13, 2026
Merged

fix(sdk): clear SonarQube ReDoS hotspot in base64url encode#62
wolpert merged 1 commit into
mainfrom
fix-base64url-redos-hotspot

Conversation

@wolpert

@wolpert wolpert commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Resolves the single SonarQube security hotspot on the browser SDK (codeheadsystems_passkeys-browser).

The hotspot

  • Rule: typescript:S5852 — slow regular expression / ReDoS (category DoS, CWE-400/CWE-1333).
  • Location: clients/passkeys-browser/src/base64url.ts:18 — the /=+$/ padding stripper in encode().

Why it was effectively safe

The regex only runs on btoa() output, where = appears solely as 0–2 trailing padding characters (never interior). The catastrophic/quadratic input S5852 warns about — a long run of = followed by a non-matching char — is therefore unreachable, and the input is the host's own bounded bytes, not attacker-controlled.

The fix (clear it at the source rather than dismiss it)

Since = only ever appears as trailing padding in base64, removing all = is equivalent to stripping a trailing run, and /=/g is a single-character, non-backtracking match:

- .replace(/=+$/, "")
+ .replace(/=/g, "")

Byte-identical output; the full vitest suite (76 tests, incl. base64url round-trips) passes. This removes the finding at the root so it can't reappear on a future scan — no manual "mark Safe" sign-off needed.

🤖 Generated with Claude Code

…+ S7781)

SonarQube flagged `/=+$/` in encode() as a slow-regex hotspot (S5852,
ReDoS/CWE-1333). It only ran on btoa() output where `=` is at most 2 trailing
padding chars, so the quadratic input was unreachable — but rather than dismiss
it, remove the regex entirely: convert all the global-regex replaces in encode()
and decode() to replaceAll() with string literals (ES2022 target). This also
satisfies S7781 ("prefer replaceAll over replace"), keeps the transforms linear
and non-backtracking, and is more readable.

Behavior-preserving: base64 only emits `=` as trailing padding, so stripping all
`=` equals stripping the trailing run; the rest are exact equivalents. Output is
byte-identical and the full vitest round-trip suite (76 tests) and tsc pass.

Refs #60

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wolpert
wolpert force-pushed the fix-base64url-redos-hotspot branch from c65e194 to 11d1086 Compare June 13, 2026 14:35
@sonarqubecloud

Copy link
Copy Markdown

@wolpert
wolpert enabled auto-merge (rebase) June 13, 2026 14:38
@wolpert
wolpert merged commit 565aaa4 into main Jun 13, 2026
5 checks passed
@wolpert
wolpert deleted the fix-base64url-redos-hotspot branch June 13, 2026 14:39
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.

1 participant