Skip to content

Rust: Add command injection query (CWE-078) - #22323

Open
lcmangalagiri wants to merge 2 commits into
github:mainfrom
lcmangalagiri:rust-cwe-078-command-injection
Open

Rust: Add command injection query (CWE-078)#22323
lcmangalagiri wants to merge 2 commits into
github:mainfrom
lcmangalagiri:rust-cwe-078-command-injection

Conversation

@lcmangalagiri

Copy link
Copy Markdown

Detects user-controlled data flowing into std::process::Command and tokio::process::Command (both command name and arguments).

Query include:

  1. Extension library with sources, sinks, and barriers
  2. Models-as-data sinks for Command::new, .arg(), .args() (std + tokio)
  3. Query help (.qhelp) with examples
  4. Test cases with inline expectations

Query ID: rust/command-line-injection

Detects user-controlled data flowing into std::process::Command and
tokio::process::Command (both command name and arguments).

- Extension library with sources, sinks, and barriers
- Models-as-data sinks for Command::new, .arg(), .args() (std + tokio)
- Query help (.qhelp) with examples
- Test cases with inline expectations

Query ID: rust/command-line-injection

@geoffw0 geoffw0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @lcmangalagiri,

I've just pushed a few commits onto this PR (I hope that's OK - I would usually do a PR onto your branch, but I don't seem to be able to do that here). Please take a look and confirm you're happy with my changes. I've addressed a few things:

  • the .expected file for the test was missing - it can be created with the codeql test run . --learn command, or using VSCode if you have things set up, but I've done that for you here.
  • I wanted to have a test that includes string concatenation, a common anti-pattern for shell command use. I've added that here as well and the query is successful on it.
  • I've also added the good and bad examples as tests, to verify that they compile and the query behaves as expected on them. We're currently getting a spurious result on the good test.
    • we can fix this with barrier guards, but I don't have time for that today.
  • the security-severity tag should ideally be generated with a (sadly internal) script, though copying from another query with the same CWE tags as you have is very likely to produce the same result. I've run the script, and in this case it did change the number slightly. I'm not sure it's critical either way.

Concern: Flagging every .arg() call may produce false positives. A hardcoded command with user-controlled arguments (e.g., Command::new("grep").arg(user_input)) is less severe than user-controlled shell commands. The query doesn't distinguish these.

I would say a case like that should at least put user_input through a "sanitizer" function of some sort. Usually we don't get taint flow through a sanitizer implementation, so there won't be a false positive result when that is done. If we do get one, and it shows up noisily in any of our various levels of real-world testing (MRVA, DCA and QA runs), we can address it then (e.g. by making the popular sanitizer function(s) into flow barriers).


Other than that, I'm very happy with this query. MRVA found some (valid) real-world results, which is a great starting point - and I think we could find more results in future with some additional models. But the next thing will be adding barrier guards and running this through CI and docs review.

I'm away on Friday, my hope is that we can finish and merge this when I'm back on Monday. Then I'll take a look at your other new query.

Comment on lines +4 to +5
// GOOD: use a fixed command with the user input as a separate argument,
// avoiding shell interpretation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found this comment slightly confusing because it's talking about things that didn't change between the Bad and Good versions.

Suggested change
// GOOD: use a fixed command with the user input as a separate argument,
// avoiding shell interpretation
// GOOD: user input is checked against an allowlist before passing into a shell command

@geoffw0

geoffw0 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

... looks like I didn't manage to push my commits to this branch. I'll have to try another way ...

@geoffw0

geoffw0 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

If you're able to add my commits, they're here: main...geoffw0:ql:rust-cwe-078-command-injection

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants