설명
Python의 eval()과 exec()는 문자열을 단순히 변환하는 API가 아닙니다. eval()은 문자열을 Python 표현식으로 해석하고, exec()는 문자열을 Python 문장 모음으로 해석하여 애플리케이션의 권한으로 실행합니다. HTTP 요청 등 신뢰할 수 없는 입력의 문자열을 이 함수에 전달하면 공격자가 애플리케이션의 제어 흐름을 바꾸는 Python 코드를 제공할 수 있습니다.
전역 및 지역 네임스페이스를 제한하거나 __builtins__ 매핑을 바꾸더라도 신뢰할 수 없는 코드를 안전하게 실행하는 보안 샌드박스가 되지는 않습니다. ast.literal_eval()은 Python 코드를 실행하지 않지만, Python 문서가 메모리·스택·CPU 고갈 가능성을 명시하므로 적대적 입력을 위한 범용 대안으로 권장할 수 없습니다.
잠재적 영향
- 애플리케이션이 접근할 수 있는 데이터의 조회, 변경 또는 유출
- 애플리케이션 상태와 제어 흐름의 변경
- 프로세스 권한으로 가능한 파일·네트워크·운영 체제 기능의 실행
- 예외, 무한 계산 또는 과도한 자원 소비로 인한 서비스 중단
명령 실행이 곧 운영 체제 권한 상승을 뜻하지는 않습니다. 실제 영향은 실행 프로세스의 권한, 사용 가능한 모듈, 비밀정보 및 네트워크 접근 범위에 따라 달라집니다.
해결 방법
- 동적 평가 경로를 제거합니다. JSON처럼 정의된 데이터 형식이 필요하면
json.loads()로 파싱하고, 요청 크기를 제한하며, 파싱 결과의 구조·형식·범위를 검증한 뒤 데이터로만 처리합니다. JSON 파싱도 큰 입력으로 자원을 소모할 수 있으므로 입력 크기 제한을 함께 적용합니다. - 사용자가 작업을 선택해야 한다면 서버가 소유한 소수의 식별자를 사전 정의된 호출 가능 객체에 매핑하고, 선택한 객체를 직접 호출합니다. 허용 목록을 통과한 이름이라도 다시 문자열에 삽입하여
eval()이나exec()에 전달하면 안 됩니다. - 제한된 전역 네임스페이스, 변경한
__builtins__, 단순 문자열 치환 또는 이름이sanitize인 도우미를 보안 경계로 사용하지 않습니다. - 신뢰할 수 없는 Python 실행 자체가 명시적인 제품 요구사항이라면 애플리케이션 프로세스에서 실행하지 않습니다. 별도의 강화된 런타임에 격리하고 CPU·메모리·실행 시간·파일 시스템·네트워크·권한을 명시적으로 제한합니다.
예시
변경 전
python
from flask import Flask, request
app = Flask(__name__)
@app.get("/evaluate")
def evaluate():
expression = request.args.get("expression", "")
result = eval(expression) # 취약: 요청 문자열을 Python 코드로 실행
return {"result": str(result)}
변경 후
python
from flask import Flask, abort, request
app = Flask(__name__)
def service_status():
return "healthy"
def application_version():
return "2.0"
OPERATIONS = {
"status": service_status,
"version": application_version,
}
@app.get("/operation")
def run_operation():
operation = OPERATIONS.get(request.args.get("name", ""))
if operation is None:
abort(400, description="Unsupported operation")
return {"result": operation()} # 서버가 등록한 객체를 직접 호출
안전한 예시는 요청값을 Python 문법으로 해석하지 않습니다. 요청값은 서버가 정의한 매핑의 키로만 사용되고, 선택된 호출 가능 객체가 직접 실행됩니다.
참조
- Python
eval()문서 - Python
exec()문서 - Python
ast.literal_eval()문서 - Python
json문서의 구현 제한 - CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code
- CWE-94: Improper Control of Generation of Code
- OWASP Top 10:2025 A05 Injection
- OWASP Top 10:2021 A03 Injection
- OWASP Code Injection
- OWASP ASVS 5.0.0 V1 Encoding and Sanitization