Skip to content

fix: distinguish runArgs flags from object members in non-devcontainer files - #93

Merged
nozaq merged 3 commits into
mainfrom
claude/runargs-false-positives-y5cwlq
Aug 1, 2026
Merged

fix: distinguish runArgs flags from object members in non-devcontainer files#93
nozaq merged 3 commits into
mainfrom
claude/runargs-false-positives-y5cwlq

Conversation

@nozaq

@nozaq nozaq commented Aug 1, 2026

Copy link
Copy Markdown
Member

Summary

This change fixes a bug where rules matching runArgs flags (like /runArgs/--volume) would incorrectly match object members with the same name in Feature and Template files, where runArgs is ordinary data rather than a command-line argument array.

Key Changes

  • Added flag pattern detection: Introduced isFlagPattern() function to identify patterns that specifically address docker run flags (e.g., /runArgs/--volume), and added a flag field to the pattern struct to track this.

  • Refined runArgs traversal logic: Moved the runArgs array check earlier in the value() method and added a guard in dispatch() to skip flag patterns when node.Arg is nil (indicating the node wasn't produced by flag parsing).

  • Updated documentation: Enhanced comments in CONTRIBUTING.md and rule.go to clarify that flag patterns only match in devcontainer.json files and that runArgs objects are traversed as ordinary data.

  • Expanded test coverage: Added test cases across multiple rule tests to verify that runArgs object members named like flags (e.g., {"runArgs": {"--privileged": true}}) are not incorrectly flagged as security issues in any file type.

Implementation Details

The fix leverages the existing node.Arg field, which is only set when a node is produced by flag parsing in runArgsFlags(). Flag patterns now skip any node where node.Arg is nil, ensuring they only match actual command-line flags in devcontainer.json files. This allows runArgs to be safely used as an object in Features and Templates without triggering false positives.

https://claude.ai/code/session_01USZT4TA9NjYxH5KiFrprXY

claude added 2 commits August 1, 2026 11:34
A "runArgs" that is an object rather than an argv is still walked as
the object it is, so a member named like a flag produced the same path
segments as a flag occurrence and matched a rule's "/runArgs/--flag"
pattern with no flag behind it. Every such rule then took its
non-"runArgs" branch and reported a finding against a property the
document does not have, e.g. `{"runArgs": {"--privileged": true}}` as
`"privileged" is set to true` — in a devcontainer-feature.json too,
where "runArgs" is read as an ordinary array.

Compile a pattern addressing a flag occurrence as such and match it
only against a node the argv traversal produced.

Document the flag addressing in CONTRIBUTING.md, where the
rule-authoring walkthrough did not mention it and the "docker run" flag
table section still said rules ask dockerargs for a flag's values
instead of matching entries themselves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USZT4TA9NjYxH5KiFrprXY
…unArgs"

The flag-pattern guard alone left "/runArgs/*" reading a "runArgs" that
is not an argv: a rule subscribing to it saw an object's members as if
they were entries, which is the same misreading, one path over. Descend
a devcontainer.json's "runArgs" only as the argv it becomes, so every
path under it — the wildcard included — arrives with Node.Arg set. The
value is still visited as a whole at "/runArgs".

The guard stays for a Feature and a Template, where "runArgs" is not a
property at all and is walked as the ordinary data it is, so a member of
it can be named like a flag without being one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USZT4TA9NjYxH5KiFrprXY
@nozaq nozaq changed the title Distinguish runArgs flags from object members in non-devcontainer files fix: distinguish runArgs flags from object members in non-devcontainer files Aug 1, 2026
The engine had been made to keep a flag-spelled pattern from matching
anything but a flag occurrence, which gave the "--" spelling a reserved
meaning under "/runArgs" in the pointer language: a Feature or a
Template has no "runArgs" property, so a member of one named like a flag
is an ordinary member and matching it is the plain reading of the path.

Restore that reading and put the guard where the ambiguity is actually
resolved. A rule reporting both a property and a flag cannot tell the
two apart by Node.Arg alone, since it is nil for the property and for
such a member alike, so the rules reporting one now ask underRunArgs
which they were handed.

no-docker-socket-mount needs no guard: it declares only Devcontainer,
whose "/runArgs" the traversal descends as the argv or not at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01USZT4TA9NjYxH5KiFrprXY
@nozaq
nozaq merged commit c7abaaa into main Aug 1, 2026
12 checks passed
@nozaq
nozaq deleted the claude/runargs-false-positives-y5cwlq branch August 1, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants