Skip to content

Commit 11d1086

Browse files
wolpertclaude
andcommitted
fix(sdk): replace base64url regexes with replaceAll (SonarQube S5852 + 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>
1 parent 539316c commit 11d1086

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

clients/passkeys-browser/src/base64url.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@ export function encode(input: ArrayBuffer | Uint8Array | ArrayBufferView): Base6
1515
for (let i = 0; i < bytes.length; i++) {
1616
s += String.fromCharCode(bytes[i]!);
1717
}
18-
return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
18+
// base64url per RFC 4648 §5: map +/ to -_ and strip padding. Using replaceAll with
19+
// string literals (no regexes) keeps this linear — it avoids the ReDoS shape
20+
// SonarQube flags on `/=+$/`. `=` only ever appears as trailing base64 padding, so
21+
// removing all of it is equivalent to stripping the trailing run.
22+
return btoa(s).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
1923
}
2024

2125
export function decode(input: Base64Url): Uint8Array {
2226
const pad = "=".repeat((4 - (input.length % 4)) % 4);
23-
const normalized = input.replace(/-/g, "+").replace(/_/g, "/") + pad;
27+
const normalized = input.replaceAll("-", "+").replaceAll("_", "/") + pad;
2428
const binary = atob(normalized);
2529
const bytes = new Uint8Array(binary.length);
2630
for (let i = 0; i < binary.length; i++) {

0 commit comments

Comments
 (0)