dcmjs: DS/IS VALUE REPRESENTATION INPUT VALIDATION BYPASS
What fixes it
- 0.52.0dcmjs, npmGitHub
npm install dcmjs@0.52.0
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
dcmjs, a JavaScript library for DICOM manipulation used in web-based medical imaging viewers, contains an input validation bypass in its handling of DS (Decimal String) and IS (Integer String) value representations.
The DecimalString and IntegerString classes in ValueRepresentation.js use a regex sanitizer followed by JavaScript's Number() constructor. While the regex strips direct NaN/Infinity strings, it preserves scientific notation (including the 'e' character), enabling:
- Infinity injection via scientific notation overflow (1e999999)
- NaN injection via sign-only remnants from stripped inf strings ("-inf" -> "-")
- IS accepting scientific notation in violation of PS3.5
AFFECTED PRODUCT ================ Product: dcmjs (JavaScript DICOM manipulation library) Repository: https://github.com/dcmjs-org/dcmjs npm: https://www.npmjs.com/package/dcmjs Affected Versions: < 0.52.0 (patched in 0.52.0, released 2026-05-19) CVE: CVE-2026-46350 (assigned by GitHub 2026-05-13) CWE: CWE-20 (Improper Input Validation) CVSS Score: 7.5 (HIGH) CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H Maintainer note: The CVSS score above is the reporter's assessment; dcmjs rates this low, because malformed input produces NaN/Infinity in values the caller must range-check in any case (both are reachable by other means, and no trust boundary enforced by dcmjs is crossed).
DOWNSTREAM IMPACT ================= dcmjs is a foundational library used by:
- OHIF Viewer (Open Health Imaging Foundation)
- Cornerstone.js ecosystem
- DICOMweb client/server implementations
- Research and clinical web-based PACS viewers
- Any Node.js or browser application parsing DICOM via dcmjs
ROOT CAUSE ========== In src/ValueRepresentation.js, both DecimalString and IntegerString use:
let returnVal = numberStr.trim().replace(/[^0-9.\\\-+e]/gi, ""); return returnVal === "" ? null : Number(returnVal);
The regex /[^0-9.\\\-+e]/gi strips characters NOT in the set {0-9, ., \, -, +, e, E}. This provides partial defense: direct "NaN" and "Infinity" strings are stripped to empty/null. However:
(a) Scientific notation is fully preserved because 'e', digits, '+', '-', '.' all pass the regex. "1e999999" passes intact, and Number("1e999999") returns JavaScript Infinity.
(b) The string "-inf" is stripped to just "-" (only the minus passes the regex). Number("-") returns JavaScript NaN.
(c) IntegerString uses the SAME regex/logic as DecimalString, meaning IS accepts scientific notation ("1e5" -> 100000) in violation of PS3.5 Section 6.2, which restricts IS to characters 0-9, +, -.
(d) No range validation exists for IS values (PS3.5 requires [-2^31, 2^31-1]) or DS values (16-character max, fixed/floating-point only).
VULNERABILITY DETAILS =====================
Attack Vector 1: Infinity via Scientific Notation Overflow ---------------------------------------------------------- Input: DS or IS field containing "1e999999" Regex: Passes (all chars in allowed set) Result: Number("1e999999") -> Infinity Impact: Infinity propagates through all downstream arithmetic
Attack Vector 2: Negative Infinity via Scientific Notation ---------------------------------------------------------- Input: DS or IS field containing "-1e999999" Regex: Passes Result: Number("-1e999999") -> -Infinity Impact: Negative Infinity in spatial/dosimetric calculations
Attack Vector 3: NaN via Sign-Only Remnant ------------------------------------------ Input: DS or IS field containing "-inf" Regex: Strips to "-" Result: Number("-") -> NaN Impact: NaN propagates silently through arithmetic (IEEE 754)
Attack Vector 4: NaN via Plus-Only Remnant ------------------------------------------ Input: DS or IS field containing "+inf" Regex: Strips to "+" Result: Number("+") -> NaN Impact: Same as above
Attack Vector 5: IS Scientific Notation Bypass ----------------------------------------------- Input: IS field containing "1e5" Regex: Passes Result: Number("1e5") -> 100000 Impact: Integer fields accept non-integer representation, violating PS3.5
Attack Vector 6: IS Extreme Overflow ------------------------------------- Input: IS field containing "1e18" Regex: Passes Result: Number("1e18") -> 1000000000000000000 Impact: Far exceeds IS range [-2^31, 2^31-1], no bounds check
CLINICAL IMPACT =============== dcmjs is used in web-based DICOM viewers and processing pipelines. Corrupted values affect:
- PixelSpacing / ImagePositionPatient: Spatial geometry corruption prevents
accurate measurement and registration in web viewers
- WindowCenter / WindowWidth: Display pipeline corruption makes images
unreadable (all black or all white)
- DoseGridScaling / NumberOfFrames: Radiation therapy dose display errors
and denial of service via frame count overflow
- RescaleSlope / RescaleIntercept: Hounsfield unit conversion produces
invalid values, corrupting quantitative analysis
- SliceThickness: Volume reconstruction fails in multiplanar reformats
Text from GitHub Advisory Database
Affected versions 2
- dcmjs, npm< 0.52.0GitHub
- dcmjs, npmfrom first release, fixed in 0.52.0OSV