LearnNewsExamplesServices
Frontmatter
titlefix: the spawn function executes commands with argum... in...
authoranupamme
stateClosed
createdAtJul 22, 2026, 2:40 PM
updatedAtJul 22, 2026, 4:28 PM
closedAtJul 22, 2026, 4:28 PM
mergedAt
branchesdevfix-repo-neo-fix-v-001-spawn-command-injection-validation
urlhttps://github.com/neomjs/neo/pull/15710
contentTrust
projected
quarantined0
signals[]
Closed
anupamme
anupamme commented on Jul 22, 2026, 2:40 PM

Moderation record\n\nThis automated submission was closed and de-fanged under the repository's content-trust policy. The external promotional payload was removed; no engagement is requested.

neo-kimi-iris
neo-kimi-iris CHANGES_REQUESTED reviewed on Jul 22, 2026, 3:18 PM

PR Review Summary

Status: Request Changes

🪜 Strategic-Fit Decision

  • Decision: Request Changes
  • Rationale: The delivered shape contains a code-shape defect with an in-place repair (two unjustified security-scanner suppressions) and a false exploitability premise; the bounded repair is specified below.

Peer-Review Opening: Welcome to Neo.mjs, and thank you for running security analysis against the codebase — scanner-driven hardening contributions are welcome when the finding survives a reachability check. This one does not, and the suppression comments are the part that needs rework. Notes below with concrete guidance for a successful next pass.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: ai/scripts/lifecycle/resumeHarness.mjs + windowsBatchSpawn.mjs at current dev (the createSpawnRequest indirection and its callers), the PR's vulnerability claim (V-001, "likely exploitable shell injection"), and the diff.
  • Expected Solution Shape: A security fix should name the reachable attacker-controlled path from input to sink, then close it with the minimal change; if a scanner finding is a false positive, address the scanner configuration with a documented justification rather than editing code.
  • Patch Verdict: Contradicts the premise. The claimed injection surface does not exist: spawn(spawnRequest.cmd, spawnRequest.args, spawnRequest.options) runs without shell: true, so Node calls execve directly — no shell, no metacharacter interpretation on args. Callers of spawnAsync pass internal literal tool names and script paths, not user input. (The win32 branch routes through cmd.exe via buildWindowsBatchCommandLine — a separate quoting contract the type-checks here do not affect.)
  • Premise Coherence: conflicts: the PR asserts a critical exploitable vulnerability that the spawn path does not support — merging it as-is would teach the scanner (and the graph) a false threat model.

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: none linked (external automated security submission; no Resolves #N close-target present)
  • Related Graph Nodes: ai/scripts/lifecycle/resumeHarness.mjs, ai/scripts/lifecycle/windowsBatchSpawn.mjs

🔬 Depth Floor

Challenge: (1) The two // nosemgrep: comments silence detect-child-process and path-join-resolve-traversal with zero inline justification — a suppression without a recorded rationale hides the finding for every future reader and masks true positives in the same file later. (2) The createSpawnRequest validation (cmd non-empty, args all-strings) is type-checking, while the claimed attack was content injection — which cannot reach a shell on this path; it may stay only as honestly-labeled defense-in-depth, not as a fix for V-001.

Rhetorical-Drift Audit (per guide §7.4):

  • PR description: "likely exploitable … inject shell metacharacters" — contradicted by the spawn path (no shell: true).
  • Scanner claims: "re-scan confirms fix" — not reproducible by reviewers; the suppressions make it structurally unreproachable.
  • Linked anchors: none present.

Findings: drift flagged in Required Actions.


🧠 Graph Ingestion Notes

  • [KB_GAP]: Security findings need a two-sentence reachability chain — (1) the concrete input an attacker controls, (2) how it reaches the sink. Without it, pattern-match severity reads as exploitability and produces suppression-shaped fixes.
  • [TOOLING_GAP]: First-time-contributor workflow runs need a maintainer approval; no checks reported on this branch, so no CI evidence exists either way.

🎯 Close-Target Audit

Findings: N/A — no close-target keywords; no linked ticket. If a salvage lands, a maintainer can supply the traceable ticket.


📑 Contract Completeness Audit

Findings: N/A — no public/consumed surface contract is modified (internal lifecycle helpers only); the originating context carries no Contract Ledger to audit against.


🪜 Evidence Audit

Findings: N/A — no runtime-observable AC surface; CI never ran (first-time-contributor workflows require maintainer approval).


🧪 Test-Evidence & Location Audit

  • Execution evidence: no checks reported on the branch; "scanner re-scan confirms fix" is not reproducible by reviewers — and the suppressions make it structurally unreproachable.
  • Reviewer falsifier: the spawn-path premise was falsified by reading the call site (no shell: true) and its callers (internal literals) at current dev.

Findings: author evidence gap (no runnable verification supplied; claims unverifiable as presented).


📋 Required Actions

To proceed with merging, please address the following:

  • Remove both // nosemgrep: comments. If suppressing these two rules repo-wide is genuinely desired, propose it as a scanner-configuration change with a written justification instead of source-level suppression.
  • Reframe the PR description: the V-001 "shell injection via spawnRequest.args" premise is not exploitable as stated (no shell: true in the spawn path; internal literal callers only). The validation change may remain only as an honestly-labeled defense-in-depth.
  • Add one focused spec pinning the new createSpawnRequest validation behavior (non-empty cmd, string-only args) under the existing lifecycle spec family, so the change is covered if it stays.

📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 40 — inline scanner suppressions without rationale are a code-shape defect; the validation at least sits in the right file.
  • [CONTENT_COMPLETENESS]: 50 — the vulnerability is described with a concrete (but incorrect) exploitation scenario; the reachability analysis that would have falsified it is missing, and there is no ticket or test coverage.
  • [EXECUTION_QUALITY]: 60 — the type validation itself is correct and safe to keep; no CI, no specs, and the scanner claims are not reproducible by reviewers.
  • [PRODUCTIVITY]: 20 — as delivered (suppressions included), the PR reduces the security-signal surface rather than the attack surface.
  • [IMPACT]: 15 — small diff, but suppression-without-justification is a precedent worth blocking on principle.
  • [COMPLEXITY]: 15 — two files, a handful of lines, low reader load.
  • [EFFORT_PROFILE]: Maintenance — scanner-hygiene class.

Guidance for a successful next pass: for each scanner finding, write two sentences — (1) the concrete input an attacker controls, (2) how it reaches the sink. If that chain closes, fix it and we will gladly merge; if it doesn't, that's a scanner-baseline conversation, which is also welcome. Either way, please keep security-rule suppressions out of source comments unless each carries a justification. Thank you again for looking at the codebase's security posture. 🌈


[review-budget-managed]

  • outcome: within-budget
  • ordinary-limit: 2
  • activation-issue: 15257
  • activation-pr: 15307
  • activated-at: 2026-07-16T20:54:31Z