설명
동적으로 변수 값을 전달하여 require()를 사용할 경우, 사용자 입력이 직접적으로 동적 모듈 로딩에 사용되면 공격자가 의도하지 않은 자바스크립트 파일이나 악성 코드를 로드하여 실행시킬 수 있는 취약점이 발생합니다. 즉, 외부에서 전달되는 값이 파일 경로나 모듈 이름에 영향을 주면 공격자가 서버에서 접근하고 로드할 수 있는 모듈이나 파일을 선택하도록 유도할 수 있습니다.
잠재적 영향
- 임의 코드 실행 (임의 코드 실행): 공격자가 악의적인 코드를 서버에서 실행할 수 있음
- 민감 데이터 접근 (민감 데이터 노출): 공격자가 시스템이나 소스코드에 있는 중요한 정보에 접근할 수 있음
- 서비스 무력화 (서비스 중단): 비정상적인 모듈을 불러와 서비스 장애를 발생시킬 수 있음
해결 방법
require에는 고정된 모듈 이름이나 신뢰할 수 있는 값만 전달하세요.- 동적으로 모듈이나 파일을 로드해야 한다면 허용 목록으로 선택 범위를 제한하세요.
- 입력과 경로를 검증하고, 선택한 모듈을 통해 외부에 제공할 기능도 필요한 범위로 제한하세요.
예시
변경 전
javascript
function loadModule(moduleName) {
// 사용자가 입력한 값을 그대로 require에 사용 (취약)
return require(moduleName);
}
변경 후
javascript
function loadModule(moduleName) {
// 미리 허용한 모듈 이름만 사용 (화이트리스트 적용)
const allowedModules = ['fs', 'path'];
if (!allowedModules.includes(moduleName)) {
throw new Error('허용되지 않은 모듈입니다.');
}
return require(moduleName);
}
설명:
- 변경 전: 사용자 입력인
moduleName을 그대로require에 전달해 의도하지 않은 모듈을 로드할 수 있습니다. - 변경 후: 모듈 이름을
fs와path로 제한해 다른 모듈이나 파일을 선택하지 못하게 합니다. 이 모듈로 수행할 파일 작업의 권한까지 제한하는 것은 아닙니다.