환경 변수를 통한 명령 주입

OS Command Injection

설명

로컬 환경 값(__dirname, process.env, process.cwd() 등)으로 동적 문자열을 만들어 child_process.exec/execSync 등에 넘기면, 셸이 공백/따옴표/세미콜론/&& 같은 특수 문자를 해석해 명령 의미가 바뀌거나 추가 명령이 실행될 수 있습니다. 특히 CI/CD 변수, .env, 실행 경로가 변경되거나 의도치 않은 문자가 포함될 때 악용이 가능합니다. 공격자는 환경 변수에 악성 값을 주입하거나 경로에 특수 문자를 섞어 임의 명령 실행, 옵션/인자 주입을 유도할 수 있습니다.

잠재적 영향

  • 임의 명령 실행: 셸 해석을 통해 추가 명령(예: && curl ... | sh)이 실행될 수 있습니다.

  • 데이터 손상/삭제: rm, tar 등 파일 조작 명령의 인자 조작으로 중요 데이터가 삭제/변조될 수 있습니다.

  • 빌드/배포 파이프라인 탈취: CI 변수/스크립트에서 악성 명령이 실행되어 공급망 공격으로 이어질 수 있습니다.

  • 권한 상승/정보 유출: 고권한 컨텍스트에서 실행 시 시스템 정보/자격증명 유출 또는 권한 상승 가능.

해결 방법

  • exec/execSync로 동적 문자열 전체를 넘기지 말고, 명령은 고정 문자열로, 인자는 배열로 분리하여 execFile/execFileSync 또는 spawn(shell:false)을 사용하세요.

  • 환경 값(경로/파일명 등)은 허용 문자(화이트리스트) 검증과 길이 제한을 적용하고, 필요한 경우 안전한 이스케이프를 적용하세요.

  • 경로는 path.resolve로 기준 디렉터리 안으로 고정하고(baseDir), startsWith 검사로 디렉터리 탈출을 차단하세요.

  • 실행할 바이너리는 절대 경로로 지정하여 PATH 오염 영향을 줄이세요.

  • CI/CD나 .env에서 가져온 값은 기본값을 안전하게 설정하고, 로그에 그대로 노출하지 마세요.

  • 필요 최소 권한 원칙으로 프로세스를 실행하고, 불필요한 환경 변수 전달을 제한하세요.

취약한 코드 및 안전한 코드 예시

취약한 코드

안전한 코드

설명:

  • 취약한 코드: exec/execSync는 문자열을 셸에 전달합니다. 환경 변수(BACKUP_FILE)에 공백, 세미콜론, && 등이 포함되면 셸이 이를 해석하여 인자 주입 또는 추가 명령 실행이 가능합니다.

  • 안전한 코드: execFileSync는 셸을 거치지 않으며, 명령과 인자를 분리해 전달합니다. 또한 허용 문자 검증과 기준 디렉터리 고정(path.resolve + startsWith)으로 경로 탈출 및 인자 조작을 차단합니다.

참조

Last updated