📂 경로 조작 및 자원 삽입 - 실습 시뮬레이터

CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

✅ 학습 진행도
  • 진단 시작
  • 경로 순회 취약점 식별
  • FilenameUtils.getName() 적용
✏️ Java 코드 에디터 취약한 코드
FileController.java 💡 Apache Commons IO의 FilenameUtils.getName()을 사용하세요.
import java.io.*;
import javax.servlet.http.*;

public class FileController {
    public void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String fileName = request.getParameter("fileName");
        
        // [취약한 코드] 외부 입력값인 fileName을 검증 없이 사용하여 
        // ../와 같은 경로 순회 문자로 시스템 파일 접근이 가능하다.
        File file = new File("/data/uploads/" + fileName);
        
        if (file.exists()) {
            FileInputStream fis = new FileInputStream(file);
            // ... 파일 전송 로직 ...
        }
    }
}
💡 수정 가이드 (KISA 가이드 기준)
1. FilenameUtils.getName() 사용 (권장)

Apache Commons IO 라이브러리의 getName() 메서드는 경로 정보를 모두 제거하고 파일명만 반환합니다.

fileName = FilenameUtils.getName(fileName); File file = new File("/data/uploads/" + fileName);
2. 경로 순회 문자 필터링 (대안)

라이브러리를 사용할 수 없는 경우, 경로 순회 문자를 체크하여 예외 처리합니다.

if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) { throw new SecurityException("Invalid filename"); }
📊 분석 결과 및 설명
🎯 목표

공격자가 ../../etc/passwd와 같은 입력을 통해 허용되지 않은 상위 디렉터리의 파일에 접근하는 것을 막아야 합니다.

⚠️ 현재 취약점

Path Traversal (CWE-22)

입력값을 그대로 경로에 결합하면 운영체제의 파일 시스템 경로 해석 규칙에 따라 의도치 않은 파일이 노출될 수 있습니다.

✅ 학습 진행도
  • 진단 시작
  • 취약한 open() 사용 확인
  • os.path.basename 사용
🐍 Python 코드 에디터 취약한 코드
file_service.py 💡 os.path.basename()으로 파일명만 추출하세요.
import os
from flask import request

def get_file_content():
    filename = request.args.get('filename')
    
    # [취약한 코드] 사용자 입력을 검증 없이 경로 구성에 사용
    # 공격자가 '../../etc/passwd' 입력 시 시스템 파일 유출
    file_path = os.path.join('/var/www/uploads', filename)
    
    if os.path.exists(file_path):
        with open(file_path, 'r') as f:
            return f.read()
    return 'File not found'
💡 수정 가이드 (Python 가이드 기준)
1. os.path.basename() 사용

입력된 경로에서 디렉터리 부분을 제거하고 파일명만 반환하여 경로 조작을 방지합니다.

filename = os.path.basename(filename) file_path = os.path.join('/var/www/uploads', filename)
📊 분석 결과 및 설명
🎯 목표

외부 입력값이 파일 시스템 경로로 사용될 때, 상위 디렉터리(..)로 이동하지 못하도록 제한해야 합니다.

⚠️ 현재 취약점

Directory Traversal

os.path.join을 사용하더라도 filename../을 포함하면 상위 경로로 이동할 수 있습니다.