[GH-ISSUE #6803] [Bug] Nested indexed source maps bypass version validation #4151

Closed
opened 2026-10-31 00:47:12 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6803

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

The production traceSourceMap function accepts a nested indexed map whose version is 2, null, omitted, or the string "3". Each invalid variant returns a mapped original.ts position, embedded text, content_position: "verified-in-embedded-text", and an empty diagnostics array.

REA's inspectSourceMapEnvelope rejects the same four inputs as malformed, identifying section path [0] with Indexed source-map section map is not a version 3 map. A numeric-version-3 control succeeds in both consumers.

These are executed source-import observations, not a CLI/MCP reproduction. Each variant was run once before drafting; no target JavaScript or remote resource was executed or fetched.

Reproduction

Use the source revision below with its locked dependencies installed and Node.js v24.22.1. From the checkout, create a disposable layout so ../rea in the probe resolves to that checkout:

mkdir -p /tmp/rea-map-version/evidence
ln -s "$PWD" /tmp/rea-map-version/rea

Save the following as /tmp/rea-map-version/evidence/probe.mts:

import {traceSourceMap} from '../rea/src/javascript/sourceMaps/TraceSourceMap.ts';
import {inspectSourceMapEnvelope} from '../rea/src/domain/sourceMapEnvelope.ts';
const leaf={version:3,sources:['original.ts'],sourcesContent:['hello'],names:[],mappings:'AAAA'};
for (const version of [3,2,null,undefined,'3']) {
 const inner={...(version===undefined?{}:{version}),sections:[{offset:{line:0,column:0},map:leaf}]};
 const value={version:3,sections:[{offset:{line:0,column:0},map:inner}]};
 const envelope=inspectSourceMapEnvelope(value);
 try {const r=traceSourceMap(JSON.stringify(value),'https://example.invalid/bundle.js.map',{line:1,column:0});console.log(JSON.stringify({version:version??(version===null?'null':'omitted'),envelope,lookup:r.lookup,matches:r.matches}));}
 catch(error) {console.log(JSON.stringify({version,error:String(error),envelope}));}
}

Run from the checkout:

node_modules/.bin/tsx /tmp/rea-map-version/evidence/probe.mts

This is the executed probe with generic scratch-directory names substituted. The original source revision remained unchanged.

Expected behavior

Apply the version-3 header constraint to every embedded map, including an indexed map containing further sections. The invalid variants should produce an explicit malformed/unsupported-format outcome rather than successful original-position facts. Preserve the valid numeric-version-3 control.

This expectation is grounded in REA's documented regular and inline indexed map support, the literal-3 header schema, and the existing nested-map validation. The executed envelope validator also demonstrates the intended refusal.

Impact and scope

The tracing decoder interprets descendants of a malformed or unsupported indexed map as admitted version-3 source facts. Its acceptance depends on whether the invalid map is an indexed ancestor rather than a root or ordinary leaf. This creates inconsistent format admission and can conceal malformed metadata from callers relying on successful tracing.

Observed on five small synthetic inputs, with four invalid ancestors and one valid control. Real-producer prevalence, public CLI/MCP behavior, packaged-release behavior, and browser-collection behavior were not measured. No code execution, file mutation, data loss, or security consequence is claimed.

REA version

Source main 60accad2de8f2862fe91901502fe26cc5390fb36, package manifest 6.7.0. The source functions ran through locked tsx; the published npm artifact was not executed for this report.

Runtime and platform

Node.js v24.22.1, Linux x86_64, locked @jridgewell/trace-mapping 0.3.31. No analysis backend or browser required.

Target and artifact context

UTF-8 JSON version-3 root, one embedded indexed ancestor, and one ordinary version-3 leaf containing sources: ["original.ts"], sourcesContent: ["hello"], and mappings: "AAAA". All section offsets are zero in their own nesting level; there are no sibling sections, overlap, or external URLs.

Interface

Other

Earliest failure stage

Request parsing or validation

Relevant output or evidence

Abbreviated actual output:

inner version 3:       envelope.status=included; trace returns mapped original.ts
inner version 2:       envelope.status=malformed; trace returns mapped original.ts
inner version null:    envelope.status=malformed; trace returns mapped original.ts
inner version omitted: envelope.status=malformed; trace returns mapped original.ts
inner version "3":     envelope.status=malformed; trace returns mapped original.ts

Each successful trace returned:

{
  "state": "mapped",
  "section_path": [0, 0],
  "reported_source": "original.ts",
  "resolved_url": "https://example.invalid/original.ts",
  "original_position": {
    "line": 1,
    "column": 0,
    "offset": 0,
    "content_position": "verified-in-embedded-text"
  }
}

Evidence provenance: direct execution of the exported production tracer and envelope validator on the same objects. Local verification: reproduced. Reproduction completeness: complete for these source-import cases. CLI/MCP, browser collection and the npm release remain untested.

Typed outcome or recovery expected

Reject the invalid nested map with a format-specific result identifying the offending section, and avoid publishing its descendant mapping as an admitted source-map result.

Analysis or suspected cause

Source-derived: inspectSourceMapValue applies mapHeaderSchema.parse only to the root. During traversal, an indexed node enters addSections and continues before the ordinary leaf schema can validate its header. classifySourceMapSections checks whether sections is an array, without establishing the nested map's version. Thus indexed ancestors bypass both available version checks.

Additional context

Related #6614 concerns equal sibling offsets and an empty section; this fixture has no sibling sections. Closed #5469 concerns missing mappings on an ordinary map consumed by JavaScript application analysis; the ordinary leaf here has valid mappings. Neither is the nested indexed-header omission.

Prepared with AI assistance. The initial local open-issue corpus and all-state GitHub searches for source-map version validation and nested indexed versions did not reveal this root cause. Open and closed searches were repeated immediately before submission, together with a canonical listing of recent open issues. The recent #6790 report concerns module asset path aliases, not source-map format admission.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Four malformed or unsupported nested headers passed tracing admission and produced mapped source facts, while the existing envelope validator rejected the same inputs. The observed defect is bounded to nested indexed ancestors.
  • Workaround status: unverified
  • Workaround basis: The separate envelope validator identifies all four bad variants, but no normal CLI/MCP workflow applying that prevalidation was demonstrated.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6803 ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area Evidence, artifacts, or reconstruction ## Observed behavior The production `traceSourceMap` function accepts a nested indexed map whose `version` is `2`, `null`, omitted, or the string `"3"`. Each invalid variant returns a mapped `original.ts` position, embedded text, `content_position: "verified-in-embedded-text"`, and an empty diagnostics array. REA's `inspectSourceMapEnvelope` rejects the same four inputs as `malformed`, identifying section path `[0]` with `Indexed source-map section map is not a version 3 map.` A numeric-version-3 control succeeds in both consumers. These are executed source-import observations, not a CLI/MCP reproduction. Each variant was run once before drafting; no target JavaScript or remote resource was executed or fetched. ## Reproduction Use the source revision below with its locked dependencies installed and Node.js v24.22.1. From the checkout, create a disposable layout so `../rea` in the probe resolves to that checkout: ```sh mkdir -p /tmp/rea-map-version/evidence ln -s "$PWD" /tmp/rea-map-version/rea ``` Save the following as `/tmp/rea-map-version/evidence/probe.mts`: ```ts import {traceSourceMap} from '../rea/src/javascript/sourceMaps/TraceSourceMap.ts'; import {inspectSourceMapEnvelope} from '../rea/src/domain/sourceMapEnvelope.ts'; const leaf={version:3,sources:['original.ts'],sourcesContent:['hello'],names:[],mappings:'AAAA'}; for (const version of [3,2,null,undefined,'3']) { const inner={...(version===undefined?{}:{version}),sections:[{offset:{line:0,column:0},map:leaf}]}; const value={version:3,sections:[{offset:{line:0,column:0},map:inner}]}; const envelope=inspectSourceMapEnvelope(value); try {const r=traceSourceMap(JSON.stringify(value),'https://example.invalid/bundle.js.map',{line:1,column:0});console.log(JSON.stringify({version:version??(version===null?'null':'omitted'),envelope,lookup:r.lookup,matches:r.matches}));} catch(error) {console.log(JSON.stringify({version,error:String(error),envelope}));} } ``` Run from the checkout: ```sh node_modules/.bin/tsx /tmp/rea-map-version/evidence/probe.mts ``` This is the executed probe with generic scratch-directory names substituted. The original source revision remained unchanged. ## Expected behavior Apply the version-3 header constraint to every embedded map, including an indexed map containing further sections. The invalid variants should produce an explicit malformed/unsupported-format outcome rather than successful original-position facts. Preserve the valid numeric-version-3 control. This expectation is grounded in REA's [documented regular and inline indexed map support](https://github.com/morluto/rea/blob/60accad2de8f2862fe91901502fe26cc5390fb36/docs/web-source-location.md#L63-L71), the [literal-3 header schema](https://github.com/morluto/rea/blob/60accad2de8f2862fe91901502fe26cc5390fb36/src/javascript/sourceMaps/SourceMapFormat.ts#L25-L29), and the [existing nested-map validation](https://github.com/morluto/rea/blob/60accad2de8f2862fe91901502fe26cc5390fb36/src/domain/sourceMapEnvelope.ts#L171-L177). The executed envelope validator also demonstrates the intended refusal. ## Impact and scope The tracing decoder interprets descendants of a malformed or unsupported indexed map as admitted version-3 source facts. Its acceptance depends on whether the invalid map is an indexed ancestor rather than a root or ordinary leaf. This creates inconsistent format admission and can conceal malformed metadata from callers relying on successful tracing. Observed on five small synthetic inputs, with four invalid ancestors and one valid control. Real-producer prevalence, public CLI/MCP behavior, packaged-release behavior, and browser-collection behavior were not measured. No code execution, file mutation, data loss, or security consequence is claimed. ## REA version Source main `60accad2de8f2862fe91901502fe26cc5390fb36`, package manifest 6.7.0. The source functions ran through locked `tsx`; the published npm artifact was not executed for this report. ## Runtime and platform Node.js v24.22.1, Linux x86_64, locked `@jridgewell/trace-mapping` 0.3.31. No analysis backend or browser required. ## Target and artifact context UTF-8 JSON version-3 root, one embedded indexed ancestor, and one ordinary version-3 leaf containing `sources: ["original.ts"]`, `sourcesContent: ["hello"]`, and `mappings: "AAAA"`. All section offsets are zero in their own nesting level; there are no sibling sections, overlap, or external URLs. ## Interface Other ## Earliest failure stage Request parsing or validation ## Relevant output or evidence Abbreviated actual output: ```text inner version 3: envelope.status=included; trace returns mapped original.ts inner version 2: envelope.status=malformed; trace returns mapped original.ts inner version null: envelope.status=malformed; trace returns mapped original.ts inner version omitted: envelope.status=malformed; trace returns mapped original.ts inner version "3": envelope.status=malformed; trace returns mapped original.ts ``` Each successful trace returned: ```json { "state": "mapped", "section_path": [0, 0], "reported_source": "original.ts", "resolved_url": "https://example.invalid/original.ts", "original_position": { "line": 1, "column": 0, "offset": 0, "content_position": "verified-in-embedded-text" } } ``` Evidence provenance: direct execution of the exported production tracer and envelope validator on the same objects. Local verification: reproduced. Reproduction completeness: complete for these source-import cases. CLI/MCP, browser collection and the npm release remain untested. ## Typed outcome or recovery expected Reject the invalid nested map with a format-specific result identifying the offending section, and avoid publishing its descendant mapping as an admitted source-map result. ## Analysis or suspected cause Source-derived: [`inspectSourceMapValue`](https://github.com/morluto/rea/blob/60accad2de8f2862fe91901502fe26cc5390fb36/src/javascript/sourceMaps/SourceMapFormat.ts#L313-L343) applies `mapHeaderSchema.parse` only to the root. During traversal, an indexed node enters `addSections` and `continue`s before the ordinary leaf schema can validate its header. `classifySourceMapSections` checks whether `sections` is an array, without establishing the nested map's version. Thus indexed ancestors bypass both available version checks. ## Additional context Related [#6614](https://github.com/morluto/rea/issues/6614) concerns equal sibling offsets and an empty section; this fixture has no sibling sections. Closed [#5469](https://github.com/morluto/rea/issues/5469) concerns missing `mappings` on an ordinary map consumed by JavaScript application analysis; the ordinary leaf here has valid mappings. Neither is the nested indexed-header omission. Prepared with AI assistance. The initial local open-issue corpus and all-state GitHub searches for source-map version validation and nested indexed versions did not reveal this root cause. Open and closed searches were repeated immediately before submission, together with a canonical listing of recent open issues. The recent #6790 report concerns module asset path aliases, not source-map format admission. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Four malformed or unsupported nested headers passed tracing admission and produced mapped source facts, while the existing envelope validator rejected the same inputs. The observed defect is bounded to nested indexed ancestors. - Workaround status: unverified - Workaround basis: The separate envelope validator identifies all four bad variants, but no normal CLI/MCP workflow applying that prevalidation was demonstrated.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4151
No description provided.