Skip to content

[Coding Guideline]: Prevent OS command injection #133

Open
@sei-dsvoboda

Description

@sei-dsvoboda

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()
}

Metadata

Metadata

Assignees

Labels

category: requiredA coding guideline with category requiredchapter: fficoding guidelineAn issue related to a suggestion for a coding guidelinedecidability: decidableA coding guideline which can be checked automaticallyscope: moduleA coding guideline that can be determined applied at the module levelstatus: draft

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions