Skip to content

fix(java): flag non-literal Runtime.exec args anywhere after -c - #4121

Open
protonnegativo wants to merge 1 commit into
semgrep:developfrom
protonnegativo:fix/3763-java-runtime-exec-array
Open

protonnegativo wants to merge 1 commit into
semgrep:developfrom
protonnegativo:fix/3763-java-runtime-exec-array

Conversation

@protonnegativo

Copy link
Copy Markdown

Link to an issue, if relevant

Fixes #3763

command-injection-formatted-runtime-call missed this case from the issue:

r.exec(new String[]{"/bin/sh", "-c", "some_tool", input});

The shell patterns only matched when the non-literal argument came right after "-c", and the pattern-not clauses dropped any call whose first three arguments were literals.

This changes "-c",$ARG,... to "-c",...,$ARG,... and replaces the three pattern-not clauses with a metavariable-pattern that requires $ARG to be non-literal. An all-literal call has no such $ARG, so it is still not reported.

Side effect: the same check now also applies to the $EXECUTE and $BASH variants, so calls like exec(command, "-c", "literal") are no longer reported. The old pattern-not clauses didn't cover those, and the existing tests don't exercise them.

Tests added to command-injection-formatted-runtime-call.java: the case above (ruleid) and {"/bin/sh", "-c", "some_tool", "literal"} (ok).

Before:

$ semgrep test java/lang/security/audit/
... test failed for rule id command-injection-formatted-runtime-call ... (missing findings lines 66.)
76/77: 1 unit tests did not pass

After:

$ semgrep test java/lang/security/audit/
77/77: ✓ All tests passed

Also ran semgrep --validate --config on the rule, semgrep test java (130/130, same as develop) and the lints from semgrep-rule-lints.yaml (0 findings), with semgrep 1.182.1.

command-injection-formatted-runtime-call only matched when the
non-literal argument came right after "-c", and the pattern-not
clauses dropped any call whose first three arguments were literals.
So exec(new String[]{"/bin/sh", "-c", "some_tool", input}) was missed.

Match $ARG at any position after "-c" and require it to be non-literal
through a metavariable-pattern. This replaces the three pattern-not
clauses: an all-literal call has no non-literal $ARG, so it is still
not reported.

Fixes semgrep#3763
@protonnegativo
protonnegativo marked this pull request as ready for review October 24, 2026 12:11
@CLAassistant

CLAassistant commented Oct 24, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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.

False negative in Java rule command-injection-formatted-runtime-call

2 participants