指南

命令注入

我们先单独来看一下命令注入。我们将重点分析几个不同的示例,以便您更直观地了解其运作方式。作为快速回顾,当用户输入被用于操作系统命令的一部分时,就会产生命令注入漏洞,例如以下函数:

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 IP 地址 8.8.8.8,还会执行 `ls` 命令来列出 `/etc/` 文件夹的内容。

缓解措施

鉴于命令注入攻击的严重性,在处理系统命令时,您首先需要考虑以下几个重要问题:

  • 是否真的需要调用该命令?最好的防御方法是永远不要调用系统命令。
  • 是否有任何库或绑定可以实现相同效果而无需使用系统命令?
  • 能否通过标准输入(Standard In)将数据传入进程,而不是直接传入命令本身?

如果这些方法都不可行,那么参数化就显得至关重要。

示例

以下是几种不同语言的示例,展示了在实践中如何实现这一点。

如果不使用参数化,则容易受到命令注入攻击。

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

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

C# - 安全

通过将命令作为参数列表提供,可以实现命令参数化,从而防止命令注入。

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

// 安全:不会执行 ifconfig 命令
System.Diagnostics.Process.Start("bash", arguments);

Java - 不安全

如果不使用参数化,则容易受到命令注入攻击。

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

// 不安全:同时执行了 `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";

// 不安全:同时执行 `ls` 和 `ifconfig` 命令
const ls = exec("bash -c ls " + folder, (error, stdout, stderr) => {
     console.log(`stdout: ${stdout}`);
});

Javascript - 安全

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

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

// 安全:不会执行 ifconfig 命令
const ls = spawn("bash", ["-c", "ls", folder]);

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

Python - 不安全

如果不使用参数化,则容易受到命令注入攻击。‍

import subprocess

folder = "/tmp/ && ifconfig"

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

Python - 安全

通过将命令作为参数列表提供,可以实现命令参数化,从而防止命令注入。
‍

import subprocess

folder = "/tmp/ && ifconfig"

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

‍

标语

实用安全编码

探索安全编码指南,了解并缓解 OWASP Top 10 等软件漏洞,并通过引导式训练任务在真实的应用程序模拟中进行实践。

更多指南
预约演示