fix: SAML assertion/response IDs generated with Math.random - #14
Open
jackhenry-sec-auto-remediation[bot] wants to merge 1 commit into
Conversation
Finding ID: f001 Fingerprint: f001 Severity: LOW File: lib/utils.js:59 Generated by glasswing /patch (static review)
jackhenry-sec-auto-remediation
Bot
requested a review
from a team
as a code owner
August 18, 2026 19:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
How to act on this PR
Security Vulnerability Details
lib/utils.js:59f001Vulnerability Description
SAML assertion/response IDs generated with Math.random
Root cause: lib/utils.js:60-62 getRandomInt used Math.random(), sole entropy source for exports.uid (lib/utils.js:30), which generates the SAML Response ID and Assertion IDs on all default paths. Fix draws bytes from crypto.randomBytes with rejection sampling (bytes >= 248 discarded, 248 = 62*floor(256/62)) onto the same 62-char alphabet — unpredictable and uniform. getRandomInt had no other callers and is removed. Output format unchanged so callers in lib/saml11.js and lib/saml20.js need no changes; 32-char uid now carries ~190 bits CSPRNG entropy.
Fix Applied
Diff
Variants checked
Grepped Math.random, getRandomInt, pseudoRandomBytes tree-wide. lib/saml11.js:59, lib/saml20.js:179, lib/saml20.js:195 all route exclusively through utils.uid — covered by the single fix. lib/saml11.js:137 already uses crypto.randomBytes. Zero Math.random occurrences remain under lib/.
Bypass considered
Fixing only one call site would leave the other assertion IDs predictable. Fixing inside utils.uid (and deleting getRandomInt) covers every default-path ID. Caller-supplied options.uid bypasses uid by design (out of scope). Naive randomBytes % 62 rejected due to modulo bias.
Test note
Added to test/utils.tests.js: pins Math.random to 0 — old implementation deterministically produces 32 x 'A', failing assert.notEqual; with fix output comes from crypto.randomBytes and test passes.
Review Checklist
References
/patchskill, static review)f001🤖 Generated by glasswing
/patch(static review) · PR opened by the non-LLM patch-apply process