본문으로 건너뛰기
>_ITDITD웹 보안 플랫폼

용어 사전

경로 탐색(Path Traversal)이란 — ../ 로 서버가 절대 내주면 안 되는 파일을 읽는 취약점

경로 탐색(디렉터리 탐색)은 파일명 입력에 ../ 를 섞어 의도한 폴더 밖의 파일 — .env, 설정, 키, /etc — 을 읽거나 쓰는 취약점입니다. 동작 원리와 진짜 방어법(입력을 경로로 쓰지 않기, 기준 디렉터리 안으로 가두기)을 방어 관점에서, 공격 절차 없이 설명합니다.

게시 2026-06-10 업데이트 2026-06-10 3분 읽기

"파일명 입력란에 ../ 를 넣으면 서버 깊숙한 곳의 .env 를 읽을 수 있다" — 이것이 경로 탐색입니다. 동작 원리와 확실하게 막는 방법을 설명합니다(공격 절차 없음).

어디에 나타나는가

"사용자 입력이 파일을 고른다"는 곳이라면 어디든입니다.

기능위험한 사용
다운로드 / 미리보기?file= 을 파일명으로 직접 사용
이미지 / 첨부 표시URL 파라미터로 경로의 일부를 구성
업로드저장 경로에 사용자 제공 이름 사용 (쓰기 유형 — 가장 위험)
템플릿 / 로케일 로딩?lang= 등으로 파일을 동적으로 선택

왜 통하는가

../ 는 "상위 한 단계"를 의미합니다. 앱이 공개 폴더 + 사용자 입력이어 붙여 그 파일을 연다면, 쌓인 ../ 구간이 요청을 공개 폴더 밖으로 "걸어 나가게" 합니다.

의도: /var/www/files/ + 사용자 입력
입력이 "상위로" 를 쌓음 (../ ../ ../ …)
↓ 앱이 정규화 없이 이어 붙인 뒤 open()
기준 밖에 닿음 (.env, 설정, 키, /etc) = 읽기/쓰기
기준 폴더에 사용자 입력을 이어 붙이면 쌓인 ../ 가 그 밖의 파일에 닿는다.

읽기는 정보 노출을 뜻하고, 쓰기(업로드)는 어디든 파일을 심을 수 있음을 뜻하며, 이는 RCE 로 이어질 수 있습니다.

방어: 입력을 경로로 쓰지 않기 + 기준으로 가두기

1

사용자 입력을 날것의 파일 경로로 절대 쓰지 않기 (가장 중요)

노출하는 파일은 ID → 실제 파일 허용 목록을 거쳐 해석하세요. 사용자는 식별자("3", "invoice")만 넘기고, 실제 경로는 서버가 결정합니다.

2

정규화한 뒤 기준 디렉터리 안에 머무는지 검증

언어의 리졸버(resolve/realpath)로 절대 경로로 바꾼 뒤, 그것이 허용된 기준 디렉터리로 시작하는지 검사하세요. 그 밖의 것은 모두 거부합니다. 단순한 '../' 문자열 제거는 인코딩 우회에 실패합니다.

3

앱을 최소 권한으로 실행

앱의 런타임 사용자가 읽을 수 있는 파일을 작업에 필요한 것으로 한정하세요. 누군가 빠져나가더라도 읽을 수 없는 파일은 아무것도 유출하지 않습니다.

4

비밀은 아예 공개 루트 밖에

.env, .git, 키, 백업을 애초에 웹 루트나 업로드 폴더에 두지 마세요. 배치로 공격 표면을 제거하세요.

본 사이트의 견해: 배치 실수와 연속선상에 있다 — 올바른 순서로 고쳐라

경로 탐색은 .env 노출 사고와 연속선상에 있습니다. 둘 다 "웹으로 절대 닿으면 안 되는 것이 웹으로 닿게 된" 경우입니다. 응급 처치(헤더, 단순 필터)는 증상을 가리지만, 코드와 배치가 고쳐지지 않으면 다른 경로로 여전히 유출됩니다. 순서는 (1) 입력을 경로로 쓰지 않는 코드, (2) 기준 디렉터리로 가두기, (3) 비밀을 공개 루트 밖에 두기 입니다. 진짜 해결의 형태는 공유 호스팅에서 안전한 배치를 함께 읽어 보세요.

다음으로 읽기

FAQ

Q경로 탐색으로 무엇이 유출되나요?
A

앱이 노출할 의도가 전혀 없던 파일들입니다. .env(DB 자격 증명, API 키), 설정 파일, 개인 키, 소스 코드, /etc 같은 OS 경로 등입니다. 읽기를 넘어 업로드의 저장 경로에 닿으면 어디든 쓸 수 있어 RCE(원격 코드 실행)로 확대될 수 있습니다.

Q가장 효과적인 방어법은 무엇인가요?
A

사용자 입력을 날것의 파일 경로로 절대 쓰지 마세요. 꼭 써야 한다면 허용 목록(ID/파일명의 고정된 집합)을 거쳐 매핑하고, 라이브러리로 경로를 정규화한 뒤, 결과가 허용된 기준 디렉터리 안에 머무는지 검증하세요. 확장자 검사나 단순한 '../' 제거는 우회됩니다.

Q.htaccess 나 헤더로 막으면 되지 않나요?
A

그것은 다른 문제(민감한 파일이 웹 루트에 놓인 것)에 대한 응급 처치입니다. 근본 해결은 앱 본체, .env, .git 을 공개 루트 밖에 두고, 입력을 경로로 쓰지 않는 코드를 작성하는 것입니다. 응급 처치와 진짜 해결은 별개의 작업입니다.