환경 변수를 통한 명령 주입
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