Skip to content

Security Advisory: Event-loop denial of service in SourceNode via unvalidated section offset line #76

Description

@waydeshi

Summary

Attribute Value
Vendor / Org 7rulnik (source-map-js fork)
Product source-map-js
Component lib/source-map-consumer.js (indexed-map section parsing) + lib/source-node.js (fromStringWithSourceMap)
Affected Versions >= 1.0.0, <= 1.2.1 (unfixed on main)
Severity High
CVSS 3.1 Score 7.5 (High)
CVSS 3.1 Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE CWE-1287 (Improper Validation of Specified Type of Input); also CWE-835 (Loop with Unreachable Exit Condition)
Affected File lib/source-map-consumer.js (section offset intake), lib/source-node.js:112-118

Description

An indexed source map ({ "sections": [...] }) carries a per-section offset.line. When such a
consumer is fed to SourceNode.fromStringWithSourceMap, the section offset is applied by a
line-padding loop in source-node.js that pushes one newline per line up to the mapping's generated
line. offset.line is never validated to be a bounded, non-negative integer against the actual
generated content. A crafted offset.line of 1e999 (which JSON.parse yields as Infinity), or a
merely very large finite value, forces this loop to run for an attacker-chosen number of iterations.
A large finite value blocks the Node event loop for that entire duration (a synchronous freeze); an
Infinity value drives the internal array length past the engine's limit and throws
RangeError: Invalid array length. The attacker converts a tiny indexed-map document into a
process-level stall or crash of any service that re-emits the map.

Impact

A service that re-emits untrusted indexed source maps (bundler merge step, symbolication worker)
freezes its event loop for an attacker-chosen duration or crashes with an uncatchable-in-place array
error. On a shared multi-tenant symbolication or build service, one crafted map denies service to the
other tenants whose work that process also serves.

Remediation

Recommended Fix

Validate offset.line and offset.column at section-intake time: require finite, non-negative
integers within a sane bound relative to the generated content, and throw a typed error otherwise.
Independently, cap or guard the line-padding loop in source-node.js so it cannot iterate beyond the
real generated-line count.

Workaround

Run re-emit in a child process with a wall-clock timeout and restart policy; reject indexed maps whose
sections[].offset.line is non-integer or exceeds a small bound.

References

Activity

  1. waydeshi commented on Sep 20, 2026

    @waydeshi
    Author
  2. jared-schwalbe commented on Sep 22, 2026

    @jared-schwalbe

    @7rulnik Any chance we'll see a patch for this CVE?

  3. 7rulnik commented on Sep 22, 2026

    @7rulnik
    Owner

    @jared-schwalbe yep, i will take a look

  4. zurcacielos commented on Sep 26, 2026

    @zurcacielos

    PR 78 fixes this - go test it and approve it to ease merge.

  5. 7rulnik commented on Sep 28, 2026

    @7rulnik
    Owner

    hi guys

    I am currently in location with very limited internet connection. I am planning to make a release tomorrow.

  6. Skillzore commented on Sep 30, 2026

    @Skillzore

    How is the release coming? There are a lot of libs and subsequent development teams affected by this.

  7. 7rulnik commented on Sep 30, 2026

    @7rulnik
    Owner

    fixed in #79
    will be released as 1.2.2 https://github.com/7rulnik/source-map-js/releases/tag/v1.2.2

    It's already published and right now being validated by npm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions