명령 주입
지금은 명령 인젝션 자체에 대해 살펴보겠습니다. 실제로 어떻게 작동하는지 쉽게 알 수 있도록 몇 가지 예제를 중심으로 살펴보겠습니다. 간단히 정리하자면, 명령 인젝션 취약점은 다음 함수와 같이 사용자 입력이 운영 체제 명령의 일부를 사용할 때 발생합니다:
let ip = request.params.ipAddress;
system("ping " + ip);
사용자가 `8.8.8.8`을 예로 들어 IP 주소를 제공하면 실행되는 명령은 `ping 8.8.8.8`로, 예상한 것과 정확히 일치하는 작업을 수행합니다. 그러나 사용자가 `8.8.8.8 && ls /etc/`를 제공하면 이 명령은 IP 8.8.8.8을 핑할 뿐만 아니라 `/etc/ 폴더에서 `ls`도 실행합니다.
완화
명령어 인젝션 공격의 심각성을 고려할 때, 시스템 명령어로 작업할 때 먼저 몇 가지 중요한 질문을 해야 합니다:
- 그 명령을 꼭 호출해야 하나요? 가장 좋은 방어 방법은 시스템 명령을 호출하지 않는 것입니다.
- 시스템 명령을 사용하지 않고도 동일한 효과를 얻을 수 있는 라이브러리/바인딩이 있나요?
- 명령 자체 대신 표준 인을 통해 프로세스에 데이터를 전달할 수 있나요?
이러한 작업이 불가능하다면 매개변수화가 중요합니다.
예제
다음은 실제로 어떻게 보이는지 보여드리기 위해 다양한 언어로 된 몇 가지 예제입니다.
매개변수화를 사용하지 않으면 명령어 인젝션에 취약합니다.
문자열 폴더 = "/tmp/ && ifconfig";
문자열 cmd = "\"ls " + 폴더 +"\"";
// 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 - 안전하지 않음
매개변수화를 사용하지 않으면 명령어 인젝션에 취약합니다.
문자열 폴더 = "/tmp/ && ifconfig";
// INSECURE: l` 및 `ifconfig` 명령을 모두 실행합니다
ProcessBuilder b = new ProcessBuilder("bash -c ls " + folder);
Process p = pb.start();
Java - 보안
명령을 매개변수 목록으로 제공하면 명령이 매개변수화되어 명령 인젝션으로부터 보호됩니다.
String folder = "/tmp/ && ifconfig";
// SECURE: ifconfig 명령을 실행하지 않습니다
ProcessBuilder b = new ProcessBuilder("bash", "-c", "ls", folder);
Process p = pb.start();
자바스크립트 - 안전하지 않음
매개변수화를 사용하지 않으면 명령어 인젝션에 취약합니다.
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}`);
});
자바스크립트 - 보안
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 - 안전하지 않음
매개변수화를 사용하지 않으면 명령 인젝션에 취약합니다.↪cf_200D↩
import subprocess
folder = "/tmp/ && ifconfig"
# INSECURE: ls` 및 `ifconfig` 명령을 모두 실행합니다
subprocess.run("bash -c ls " + folder, shell=True)
Python - 보안
명령을 매개변수 목록으로 제공하면 명령이 매개변수화되어 명령 인젝션으로부터 보호됩니다.
↪f_200D↩
import subprocess
folder = "/tmp/ && ifconfig"
# SECURE: ifconfig 명령을 실행하지 않음
subprocess.run(["bash", "-c", "ls", folder])