가이드라인

명령 주입

지금은 명령 인젝션 자체에 대해 살펴보겠습니다. 실제로 어떻게 작동하는지 쉽게 알 수 있도록 몇 가지 예제를 중심으로 살펴보겠습니다. 간단히 정리하자면, 명령 인젝션 취약점은 다음 함수와 같이 사용자 입력이 운영 체제 명령의 일부를 사용할 때 발생합니다:

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])