fix(packs-lab): sign-link path traversal — startswith → relative_to (CODE_REVIEW F1)
str(abs_path).startswith(str(PACK_HOST_DIR))는 trailing slash가 없어 sibling 경로(/foo/packs ↔ /foo/packs_evil)를 통과시켜 DSM API에 잘못된 호스트 경로를 전달할 수 있었음. Path.relative_to 기반으로 컴포넌트 단위 엄격 검증으로 교체. test_sign_link_rejects_sibling_path 회귀 테스트 추가 (RED → GREEN 검증).
This commit is contained in:
@@ -60,6 +60,29 @@ def test_sign_link_path_outside_base():
|
||||
assert r.status_code == 400
|
||||
|
||||
|
||||
def test_sign_link_rejects_sibling_path():
|
||||
"""PACK_HOST_DIR='/foo/packs' 일 때 '/foo/packs_evil/x.mp4' 같이 prefix만
|
||||
통과하는 sibling 경로는 거부해야 한다 (CODE_REVIEW F1, path traversal 변형).
|
||||
|
||||
기존 str.startswith 방식은 trailing slash가 없어 sibling 경로를 통과시킴.
|
||||
relative_to 기반 검증으로 교체되어야 통과한다.
|
||||
"""
|
||||
import json as _json
|
||||
from pathlib import Path
|
||||
base_resolved = Path("/foo/packs").resolve()
|
||||
# base의 자식이 아닌 sibling 경로 (예: /foo/packs_evil/...)
|
||||
sibling_posix = (base_resolved.parent / f"{base_resolved.name}_evil" / "x.mp4").as_posix()
|
||||
with patch("app.routes.PACK_HOST_DIR", base_resolved):
|
||||
body = _json.dumps(
|
||||
{"file_path": sibling_posix, "expires_in_seconds": 14400}
|
||||
).encode()
|
||||
r = client.post("/api/packs/sign-link", content=body, headers=_signed(body))
|
||||
assert r.status_code == 400, (
|
||||
f"sibling 경로 '{sibling_posix}'가 허용됨 (status={r.status_code}) "
|
||||
f"— path traversal 가능성"
|
||||
)
|
||||
|
||||
|
||||
def test_upload_invalid_token():
|
||||
r = client.post(
|
||||
"/api/packs/upload",
|
||||
|
||||
Reference in New Issue
Block a user