Repository navigation
RN consumer tooling retains an unpatched sprintf-js advisory #328
Description
Severity: Medium, from the reviewed Moderate advisory.
The retained RN 0.82.1 and RN 0.83.10 Candidate consumer locks contain Sprintf-js 1.0.3.
Both complete npm audit --json runs returned 1 on clean source 0c0279863507183c4e72386db9a4adc4f66933a5.
Each reports one concrete Moderate advisory and four inherited Moderate package records.
GHSA-hp3w-g68c-fv3c lists Sprintf-js <=1.1.3 and no patched version.
The official npm registry lists 1.1.3 as latest.
An update to that version does not clear the advisory.
The installed path is react-native -> babel-jest -> babel-plugin-istanbul -> @istanbuljs/load-nyc-config -> js-yaml -> argparse -> sprintf-js.
Jest also reaches the same leaf through a development dependency path.
The parent range is ~1.0.2.
The lock classification does not establish bundled mobile-runtime reachability.
The advisory requires attacker control of the format string.
The retained implementation passes precision values without an upper-bound check at sprintf-js/src/sprintf.js:75.
The nested Argparse formatter calls Sprintf-js at argparse/lib/help/formatter.js:16, :325, :559, and :744.
The observed NYC loader uses the YAML loader, while the separate YAML CLI imports Argparse.
Complete supported-input non-applicability remains unproved.
The Candidate audits report 52 package records from two unique advisories.
The other concrete finding is Braces, tracked in #312.
The generated lifecycle logs have matching totals, but their deleted locks prevent exact historical advisory comparison.
Required outcome
Use a supported compatible correction, or establish authoritative non-applicability for the complete supported input boundary.
Do not force a transitive major, add an override, or suppress the advisory.
No currently identified compatible leaf update satisfies this outcome.
Acceptance criteria
- Preserve the complete audit, exact lock identities, and all measured dependency paths.
- Identify the supported input boundary and exact advisory applicability.
- Apply a supported correction, or document complete non-applicability with independent review.
- Run applicable Make gates on the final clean source for any dependency correction.
- Require positive structured results, zero failures, and zero skips.
- Keep the original audit exit 1 and the lifecycle lock-retention limit visible.
Evidence: diagnose-rn-consumer-npm-advisories-0c02-report.md and its JSON index in the local release dispatch directory.
Applicable cells are both RN versions on iOS and Android.
This finding does not establish mobile-runtime exploitability or a protocol defect.
Activity
mdspinali commentedon Oct 11, 2026
Bounded current consumer review
Reviewed source: clean
538e1bf7d302d098d33659cb507a2489de761159.The complete audit retains exit status 1.
The exact Yarn lock SHA-256 is
a45d7ee796fa5fbc7bb942c4b0778d1d3092d5b87ac9c2e82989d9f0175d95e0.The current consumer resolves NYC 1.1.0, js-yaml 3.15.2, argparse 1.0.10, and sprintf-js 1.0.3.
The review used createRequire from each actual parent.
It did not substitute the separate root js-yaml 4.3.2 installation.
All 16 NYC configuration cases recorded zero sprintf loads and calls.
YAML input values, file names, extends values, and error data did not become numeric format strings.
The actual YAML CLI uses fixed Argparse declarations.
Benign and precision-bearing data probes confirmed that boundary.
Direct %.1000e, %.1000f, and %.1000g controls each caused RangeError in the installed sprintf implementation.
Caller-defined Argparse usage, description, epilog, and help declarations also reached the vulnerable API.
That caller boundary remains separate from ordinary NYC and YAML data inputs.
Executable JavaScript configurations can execute arbitrary code and do not establish safe untrusted-data handling.
The primary inspected and reran the independent diagnostic probe.
It completed 61 isolated cases and 171 checks, with zero unexpected failures or skips.
The results include intentional vulnerability demonstrations and original error exits.
Both benign and malicious explicit --compact arguments retain the CLI's separate fixed-%r SyntaxError.
No dependency correction or Make gate result is claimed by this diagnostic review.
Complete issue acceptance remains pending for the supported consumer scope.
Historical deleted lifecycle locks remain unavailable for exact comparison.
The report, input cases, outputs, source identities, and complete audit remain retained in the closeout records.
No advisory suppression or security exception was applied.
mdspinali commentedon Oct 11, 2026
Resolved on
538e1bf7d302d098d33659cb507a2489de761159through independently reviewed supported-input non-applicability.Change
The complete supported tooling boundary does not pass attacker-selected numeric precision formats to sprintf-js.
The actual consumers are the NYC YAML library loader and the shipped YAML CLI.
This disposition changes no dependency, support policy, or scanner exclusion.
The vulnerable leaf remains installed. It is not represented as patched.
Validation
Reviewed and reproduced source: clean
538e1bf7d302d098d33659cb507a2489de761159.0c0279863507183c4e72386db9a4adc4f66933a5and current dev.Source boundaries include NYC
index.js:78-82,99-134, nested js-yamlbin/js-yaml.js:24-61,84-131, and nested Argparse formatter:325,559,744.The supported consumer definitions remain in
verification/consumers/react-native/test-consumer.sh:19-49,134-198.The complete reports, package identities, exact lock blocks, authored inputs, outputs, and negative controls remain in the closeout records.
The first review imposed arbitrary third-party callers and reconstruction of deleted historical locks as extra closure conditions.
Its follow-up corrected that scope against the literal acceptance criteria.
It preserved the original vulnerability demonstrations and historical limits.
NYC executable JavaScript configurations already execute caller code.
This closure does not classify that code as safe untrusted data or declare sprintf-js safe for arbitrary callers.
The benign and malicious explicit-option cases retain the separate fixed-%r SyntaxError.
That error does not demonstrate attacker-selected numeric precision.
The original complete audits still exit 1.
Deleted generated lifecycle locks still prevent exact historical advisory comparison.
No identical deleted-lock claim or audit suppression follows from this closure.
No dependency correction occurred, so correction-specific Make gates are not claimed.
This resolves #328's accepted applicability route. Braces and the Assembler finding remain open in #312 and #330.