Summary
Netsuke appends build targets directly after its trusted Ninja options without inserting Ninja's -- option terminator.
On main at ac10b783f33661a0af27bd8f5d19065f095f98db, configure_ninja_build_command() constructs the base command with -j and -f <generated-build-file>, then calls:
cmd.args(targets.as_slice());
Ninja continues parsing options in that suffix. A target string beginning with - can therefore alter Ninja's control plane instead of naming a target. This affects both explicit CLI targets and project-configured default_targets; the two Codex findings are the same argv-boundary defect.
Reproduction
A bounded reproduction against Ninja 1.12.1 used a trusted build file and an attacker-controlled sibling directory containing another build.ninja.
Without a terminator:
ninja safe -C ../evil default
Ninja entered ../evil, loaded its build file, executed its recipe, and returned success.
With a terminator:
ninja -- safe -C ../evil default
Ninja treated -C and its following strings as target operands; the attacker-controlled recipe did not run.
The same primitive permits later -f, -t, -j, and other recognized Ninja options. For example, project configuration can supply:
default_targets = ["-f", "evil.ninja"]
When the user invokes netsuke or netsuke build without explicit targets, the resulting argv selects the attacker's Ninja file after Netsuke has already supplied its generated one.
std::process::Command correctly prevents shell metacharacter injection, but it does not distinguish child-program options from operands.
Impact
An attacker who can influence a target name forwarded by a developer/CI wrapper, or who controls automatically discovered project configuration, can redirect Ninja to an attacker-selected directory, build file, tool mode, or option set. That can execute attacker-controlled build recipes with the invoking developer or CI account's ambient filesystem and environment privileges.
Required change
Insert a literal -- between all Netsuke-owned Ninja options and every build-target operand:
ninja ... -f <generated-build-file> -- <targets...>
Use the same command-shaping path for explicit and configured default targets. If supported Ninja versions behave differently for an empty operand list, insert the terminator whenever the selected target list is non-empty; otherwise prefer one uniform argv shape.
Do not solve this solely by rejecting leading hyphens. Ninja can represent unusual literal target names, and the child program already provides the correct operand boundary.
Acceptance criteria
References
Summary
Netsuke appends build targets directly after its trusted Ninja options without inserting Ninja's
--option terminator.On
mainatac10b783f33661a0af27bd8f5d19065f095f98db,configure_ninja_build_command()constructs the base command with-jand-f <generated-build-file>, then calls:Ninja continues parsing options in that suffix. A target string beginning with
-can therefore alter Ninja's control plane instead of naming a target. This affects both explicit CLI targets and project-configureddefault_targets; the two Codex findings are the same argv-boundary defect.Reproduction
A bounded reproduction against Ninja 1.12.1 used a trusted build file and an attacker-controlled sibling directory containing another
build.ninja.Without a terminator:
Ninja entered
../evil, loaded its build file, executed its recipe, and returned success.With a terminator:
Ninja treated
-Cand its following strings as target operands; the attacker-controlled recipe did not run.The same primitive permits later
-f,-t,-j, and other recognized Ninja options. For example, project configuration can supply:When the user invokes
netsukeornetsuke buildwithout explicit targets, the resulting argv selects the attacker's Ninja file after Netsuke has already supplied its generated one.std::process::Commandcorrectly prevents shell metacharacter injection, but it does not distinguish child-program options from operands.Impact
An attacker who can influence a target name forwarded by a developer/CI wrapper, or who controls automatically discovered project configuration, can redirect Ninja to an attacker-selected directory, build file, tool mode, or option set. That can execute attacker-controlled build recipes with the invoking developer or CI account's ambient filesystem and environment privileges.
Required change
Insert a literal
--between all Netsuke-owned Ninja options and every build-target operand:Use the same command-shaping path for explicit and configured default targets. If supported Ninja versions behave differently for an empty operand list, insert the terminator whenever the selected target list is non-empty; otherwise prefer one uniform argv shape.
Do not solve this solely by rejecting leading hyphens. Ninja can represent unusual literal target names, and the child program already provides the correct operand boundary.
Acceptance criteria
--immediately before target operands.default_targetsfrom configuration use the same protected path.['-f', 'evil.ninja']cannot replace the generated build file.-- -C evil defaultcannot change Ninja's working directory.Commandargv ordering, including no-target and multi-target cases.make check-fmt,make lint, andmake testpass.References