准则

指令注入

让我们先看看命令注入本身。我们主要将重点放在几个不同的示例上,这样更容易看到它在实际操作中的样子。因此,作为快速复习,当用户输入使用了操作系统命令的一部分时,就会出现命令注入漏洞,比如下面的函数:

let ip = request.params.ipAddress;

system("ping " + ip);

如果用户提供了 IP 地址(我们以 `8.8.8.8` 为例),执行的命令将是 `ping 8.8.8.8`,其功能与预期的完全相同。但是,如果用户提供的是 `8.8.8.8 && ls /etc/`,那么这条命令就不仅仅是ping 8.8.8.8 这个 IP 地址了,它还会在 `/etc/ 文件夹中运行 `ls`。 

缓解

鉴于命令注入攻击的严重性,在处理系统命令时首先要问一些重要问题:

  • 你真的需要调用该命令吗?最好的办法就是永远不要调用系统命令
  • 是否有任何库/绑定可以让您在不使用系统命令的情况下实现相同的效果?
  • 能否通过 "标准输入 "而不是命令本身将数据传入进程? 

如果无法做到这些,参数化就很重要。

实例

下面是一些不同语言的示例,帮助您了解实际应用中的情况。 

如果不使用参数化,就很容易发生命令注入。

string folder = "/tmp/ && ifconfig";
string cmd = "\"ls " + folder +"\"";

// INSECURE:同时执行 `ls` 和 `ifconfig` 命令
System.Diagnostics.Process.Start("bash", "-c " + cmd);

C# - 安全

通过以参数列表的形式提供命令,可以对命令进行参数化,防止命令注入。

string folder = "/tmp/ && ifconfig";
List<string> arguments = new List<string>() {"-c", "ls", folder}; 

// SECURE: Does not execute ifconfig command
System.Diagnostics.Process.Start("bash", arguments);

Java - 不安全

如果不使用参数化,就很容易发生命令注入。

String folder = "/tmp/ && ifconfig";

// INSECURE:同时执行 `ls` 和 `ifconfig` 命令
ProcessBuilder b = new ProcessBuilder("bash -c ls " + folder);

Process p = pb.start();

Java - 安全

通过以参数列表的形式提供命令,可以对命令进行参数化,防止命令注入。

String folder = "/tmp/ && ifconfig";

// 安全:不执行 ifconfig 命令
ProcessBuilder b = new ProcessBuilder("bash", "-c", "ls", folder);

Process p = pb.start();

Javascript - 不安全

如果不使用参数化,就很容易发生命令注入。

const { exec } = require("child_process");

const folder = "/tmp/ && ifconfig";

// INSECURE: Executes both the `ls` and `ifconfig` command 
const ls = exec("bash -c ls " + folder, (error, stdout, stderr) => {
     console.log(`stdout: ${stdout}`);
});

Javascript - 安全

const { spawn } = require("child_process");

const folder = "/tmp/ && ifconfig";

// SECURE: Does not execute ifconfig command
const ls = spawn("bash", ["-c", "ls", folder]);

ls.stdout.on("data", data => {
    console.log(`stdout: ${data}`);
});

Python - 不安全

如果不使用参数化,就很容易出现命令注入问题

import subprocess

folder = "/tmp/ && ifconfig"

# INSECURE:同时执行 `ls` 和 `ifconfig` 命令
subprocess.run("bash -c ls " + folder, shell=True)

Python - 安全


import subprocess

folder = "/tmp/ && ifconfig"

# 安全:不执行 ifconfig 命令
subprocess.run(["bash", "-c", "ls", folder])