Description
Chapter
FFI
Guideline Title
Prevent OS command injection
Category
Required
Status
Draft
Release Begin
1.3.0
Release End
latest
FLS Paragraph ID
fls_djlglv2eaihl
Decidability
Decidable
Scope
Module
Tags
security, injection, sanitization
Amplification
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.
Instead, an untrusted input should be passed as a single argument.
Exception(s)
No response
Rationale
When preparing a command to be executed by the operating system, untrusted input should be sanitized to make sure it does not alter the syntax of the command to be executed. The easiest way to do this is to avoid string concatenation or formatting (a la format!()
), and provide the untrusted data as a lone argument.
Non-Compliant Example - Prose
The following code lists the contents the directory provided in the dir
variable.. However, since this variable is untrusted, a dir
such as dummy && echo BOO
will cause the command to be executed. Thus, the program prints "BOO".
Non-Compliant Example - Code
use std::process::{Command, Output};
use std::io;
fn files(dir: &str) -> io::Result {
return Command::new("sh")
.arg("-c")
.arg(format!("ls {dir}"))
.output()
}
Compliant Example - Prose
An untrusted input should be passed as a single argument. This prevents any spaces or other shell punctuation in the input from being misinterpreted by the OS command interpreter.
Compliant Example - Code
fn files(dir: &str) -> io::Result {
return Command::new("ls")
.arg(dir)
.output()
}