Skip to content

[Coding Guideline] Prevent OS Command Injection#370

Open
sei-dsvoboda wants to merge 7 commits into
mainfrom
guideline/prevent-os-cmd-injection
Open

[Coding Guideline] Prevent OS Command Injection#370
sei-dsvoboda wants to merge 7 commits into
mainfrom
guideline/prevent-os-cmd-injection

Conversation

@sei-dsvoboda

@sei-dsvoboda sei-dsvoboda commented Jan 13, 2026

Copy link
Copy Markdown
Collaborator

Closes #360

This is a new Rust rule based on the CERT Java rule IDS07-J.

@netlify

netlify Bot commented Jan 13, 2026

Copy link
Copy Markdown

Deploy Preview for scrc-coding-guidelines ready!

Name Link
🔨 Latest commit 8bf8735
🔍 Latest deploy log https://app.netlify.com/projects/scrc-coding-guidelines/deploys/698b67f87a19bc0008aef8d0
😎 Deploy Preview https://deploy-preview-370--scrc-coding-guidelines.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@felix91gr

felix91gr commented Jan 16, 2026

Copy link
Copy Markdown
Collaborator

@PLeVasseur should the bot not be assigning a reviewer automatically for pull requests as well? Or perhaps it's not automatic because it doesn't come from a template?

Anywho, here if I understand it correctly we should do the /r? command?

@felix91gr

Copy link
Copy Markdown
Collaborator

@sei-dsvoboda I've edited your original message to make Github close the original issue once this PR gets merged :)

@github-actions

Copy link
Copy Markdown
Contributor

👋 Hey @alexandruradovici! You've been assigned to review this coding guideline PR.

Your Role as Reviewer

As outlined in our contribution guide, please:

  1. Begin your review within 14 days
  2. Provide constructive feedback on the guideline content, examples, and formatting
  3. Iterate with @sei-dsvoboda - they may update the PR based on your feedback
  4. When the guideline is ready, approve and add to the merge queue

Review Checklist

  • Guideline title is clear and follows conventions
  • Amplification section expands on the title appropriately
  • Rationale explains the "why" effectively
  • Non-compliant example(s) clearly show the problem
  • Compliant example(s) clearly show the solution
  • Code examples compile (check the CI results)
  • FLS paragraph ID is correct

Bot Commands

If you need to pass this review:

  • @guidelines-bot /pass [reason] - Pass just this PR to the next reviewer
  • @guidelines-bot /away YYYY-MM-DD [reason] - Step away from the queue until a date
  • @guidelines-bot /release [@username] [reason] - Release assignment (yours or someone else's with triage+ permission)

To assign someone else:

  • @guidelines-bot /r? @username - Assign a specific reviewer
  • @guidelines-bot /r? producers - Request the next reviewer from the queue

Other commands:

  • @guidelines-bot /claim - Claim this review for yourself
  • @guidelines-bot /label +label-name - Add a label
  • @guidelines-bot /label -label-name - Remove a label
  • @guidelines-bot /queue - Show reviewer queue
  • @guidelines-bot /commands - Show all available commands

@plaindocs

Copy link
Copy Markdown
Collaborator

Hey @alexandruradovici would you like to claim this review, or let someone else grab it?

:scope: module
:tags: injection,sanitization

Commands that are passed to an external OS command interpreter, like ``std::process::Command``, should not allow untrusted input to be parsed as part of the command syntax.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In my view, Command is actually performing this, the problem is when it is used with sh -c, meaning the Command runs the interpreter. I think one should never actually run the interpreter, rather than taking care of the parameters.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hello, @alexandruradovici
I would agree that running the "sh" interpreter enables the command injection here. There are two general approaches: first, you would sanitize the arguments to prevent anything malicious from happening. Second, you use a less powerful command, such as invoking 'ls' directly without 'sh', or using fs::read_dir()...both compliant solutions use this second technique.

Are you suggesting a change in the wording, or in the code examples?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

My suggestion is to use a more powerful command and advise agains running the interpreter (sh or equivalent) with any command. I would not relate it to the arguments, but to the what kind of commands should or should not be ran.

@felix91gr felix91gr Feb 18, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I wonder how we should do this.

Something that seems simple enough to do is a deny-list:

  • In the worst case, we would be denying non-injection-allowing programs. This is fine, as a failure on our labeling would not lead to a safety hazard.
  • An allow list would have the opposite problem: if we fail to account for injectability in a program we mark as "okay", we would be giving the 👍🏻 to a safety hazard. That's why I think an allow list would probably be bad to have.
  • For all other command-line programs, we give the user some criteria by which they might be able to know if running it is okay or not (in a non-ambiguous way)

That criteria could be something along the lines of...

  • "The program must not be turing-complete given its input": this would deny all possible injection mechanisms, but some valid programs could be denied as well. For example, a program that does arbitrary computation inside its own "isolated world" would be fine to run, but would not be allowed by this rule.
  • "The program must not be able to transitively spawn an arbitrary number of other processes": this would be a lot harder to assess, but feels a lot closer to what we want to avoid.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I would not relate it to the arguments, but to the what kind of commands should or should not be ran.

Ultimately, This is a Rust rule. I don't want the rule to blacklist some commands, because we can't make that blacklist complete. Too many shell commands + too many OS platforms. Creating a whitelist of 'benign' commands is safer, but no less Herculean a problem.

You also have the problem of when arguments are tokenized on Windows (see the BatBadBut vul).

We could try to limit commands in terms of Turing-completeness, but that also sounds like a huge rabbit hole. Which of these commands would we be forbidden from running: bash, python, sqlite3, jq, gcc ?

The only other option I see would be to forbid Commands entirely (at least for security-critical code). Allow exceptions only on an individual basis. Or allow Commands only in unsafe code.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I would not relate it to the arguments, but to the what kind of commands should or should not be ran.

Ultimately, This is a Rust rule. I don't want the rule to blacklist some commands, because we can't make that blacklist complete. Too many shell commands + too many OS platforms. Creating a whitelist of 'benign' commands is safer, but no less Herculean a problem.

You also have the problem of when arguments are tokenized on Windows (see the BatBadBut vul).

We could try to limit commands in terms of Turing-completeness, but that also sounds like a huge rabbit hole. Which of these commands would we be forbidden from running: bash, python, sqlite3, jq, gcc ?

The only other option I see would be to forbid Commands entirely (at least for security-critical code). Allow exceptions only on an individual basis. Or allow Commands only in unsafe code.

As an addition to this, I do agree that creating a whitelist is much more feasible, especially when taking into accounts commands such as python3, ruby, gcc, etc.

The way I think should be handled is to pair it with an appropriate enum group of allowed commands (and their arguments). I think this could also be beneficial in case a program needs to run specific commands in parts of the code so that these could be somewhat module-locked (ie. python3 can be run exclusively in a test module paired with #[cfg(test)] or one where you need to externally call Python without using PyO3 or equivalent).

Unfortunately which commands should be whitelisted will mostly rely on a case-by-case basis so we cannot really outright suggest "accept this and not this", but within a program's scope the team in charge of designing and building said program should have mapped adequately which commands they'll need to call; the advantage of grouping them in an enum will also make verifying them through match blocks a bit easier than manually scanning the whole codebase.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Rectified PR #370: latest review by @alexandruradovici is COMMENTED; refreshed reviewer activity.

4 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

✅ Rectified PR #370: latest review by @alexandruradovici is COMMENTED; refreshed reviewer activity.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Rectified PR #370: latest review by @alexandruradovici is COMMENTED; refreshed reviewer activity.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Rectified PR #370: latest review by @alexandruradovici is COMMENTED; refreshed reviewer activity.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Rectified PR #370: latest review by @alexandruradovici is COMMENTED; refreshed reviewer activity.

@felix91gr felix91gr added the CERT C Issues or coding guidelines directly related to the CERT C Coding Guidelines label Feb 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Review Reminder

Hey @alexandruradovici, it's been more than 14 days since you were assigned to review this.

Please take one of the following actions:

  1. Begin your review - Post a comment with your feedback
  2. Pass the review - Use @guidelines-bot /pass [reason] to assign the next reviewer
  3. Step away temporarily - Use @guidelines-bot /away YYYY-MM-DD [reason] if you need time off

If no action is taken within 14 days, you may be transitioned from Producer to Observer status per our contribution guidelines.

Life happens! If you're dealing with something, just let us know.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

6 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

5 similar comments
@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

🔔 Transition Period Ended

@alexandruradovici, the 14-day transition period has passed without activity on this review.

Per our contribution guidelines, this may result in a transition from Producer to Observer status.

The review will now be reassigned to the next person in the queue.

If you believe this is in error or have extenuating circumstances, please reach out to the subcommittee.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Review Reminder

Hey @alexandruradovici, it's been more than 14 days since you were assigned to review this.

Please take one of the following actions:

  1. Begin your review - Post a comment with your feedback
  2. Pass the review - Use @guidelines-bot /pass [reason] to assign the next reviewer
  3. Step away temporarily - Use @guidelines-bot /away YYYY-MM-DD [reason] if you need time off

If no action is taken within 14 days, you may be transitioned from Producer to Observer status per our contribution guidelines.

Life happens! If you're dealing with something, just let us know.

@github-actions github-actions Bot added the status: awaiting contributor response Reviewer-bot is waiting on contributor follow-up or completion label Mar 26, 2026
Comment on lines +64 to +74
fn files(dir: &str) -> io::Result<Output> {
return Command::new("ls")
.arg(dir)
.output();
}

fn main() {
if cfg!(unix) {
let _ = files("dummy | echo BOO"); // Command is invalid, but does not print BOO
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Following the examples from CERT J, it would also be good to show the corresponding non-compliant code in Windows for the final guideline

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've tried to make the code more platform-independent. AFAICT the Windows-specific code would be identical, except s/ls/dir/g;.

:scope: module
:tags: injection,sanitization

Commands that are passed to an external OS command interpreter, like ``std::process::Command``, should not allow untrusted input to be parsed as part of the command syntax.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I would not relate it to the arguments, but to the what kind of commands should or should not be ran.

Ultimately, This is a Rust rule. I don't want the rule to blacklist some commands, because we can't make that blacklist complete. Too many shell commands + too many OS platforms. Creating a whitelist of 'benign' commands is safer, but no less Herculean a problem.

You also have the problem of when arguments are tokenized on Windows (see the BatBadBut vul).

We could try to limit commands in terms of Turing-completeness, but that also sounds like a huge rabbit hole. Which of these commands would we be forbidden from running: bash, python, sqlite3, jq, gcc ?

The only other option I see would be to forbid Commands entirely (at least for security-critical code). Allow exceptions only on an individual basis. Or allow Commands only in unsafe code.

As an addition to this, I do agree that creating a whitelist is much more feasible, especially when taking into accounts commands such as python3, ruby, gcc, etc.

The way I think should be handled is to pair it with an appropriate enum group of allowed commands (and their arguments). I think this could also be beneficial in case a program needs to run specific commands in parts of the code so that these could be somewhat module-locked (ie. python3 can be run exclusively in a test module paired with #[cfg(test)] or one where you need to externally call Python without using PyO3 or equivalent).

Unfortunately which commands should be whitelisted will mostly rely on a case-by-case basis so we cannot really outright suggest "accept this and not this", but within a program's scope the team in charge of designing and building said program should have mapped adequately which commands they'll need to call; the advantage of grouping them in an enum will also make verifying them through match blocks a bit easier than manually scanning the whole codebase.

@netlify

netlify Bot commented Jun 2, 2026

Copy link
Copy Markdown

Deploy Preview for scrc-coding-guidelines failed.

Name Link
🔨 Latest commit 8a31c99
🔍 Latest deploy log https://app.netlify.com/projects/scrc-coding-guidelines/deploys/6a1eddce3c58aa0008c2c679

@github-actions github-actions Bot added status: reviewer reassignment needed Reviewer-bot exhausted the active reviewer cycle and reassignment may be needed and removed status: awaiting contributor response Reviewer-bot is waiting on contributor follow-up or completion labels Jun 2, 2026

@felix91gr felix91gr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Filed the missing example under #578, otherwise let's merge it to preserve our sanity

@plaindocs

plaindocs commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Here is the report.md with changes in FLS which may or may not be relevant

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

Labels

CERT C Issues or coding guidelines directly related to the CERT C Coding Guidelines coding guideline An issue related to a suggestion for a coding guideline status: reviewer reassignment needed Reviewer-bot exhausted the active reviewer cycle and reassignment may be needed

Development

Successfully merging this pull request may close these issues.

[Coding Guideline]: Prevent OS Command Injection

6 participants