Swift 경로 조작 취약점

Swift 경로 조작 취약점

설명

사용자 입력을 파일 경로로 직접 사용하면 공격자가 ../ 같은 경로 요소를 이용해 허용된 디렉터리 밖의 파일을 읽거나 수정할 수 있습니다.

잠재적 영향

  • 민감 파일 읽기
  • 임의 파일 삭제 또는 덮어쓰기
  • 앱 샌드박스 내 데이터 노출

해결 방법

  1. 사용자 입력을 파일 경로로 직접 사용하지 않습니다.
  2. 기준 디렉터리와 결합한 뒤 표준화하고 결과가 기준 디렉터리 안에 있는지 확인합니다.
  3. 파일명은 허용 문자와 허용 확장자 목록으로 제한합니다.

예시

변경 전

swift
let fileName = readLine()!
let contents = try String(contentsOfFile: fileName)

변경 후

swift
import Foundation

enum PathValidationError: Error {
    case invalidFileName
    case outsideBaseDirectory
}

func readUpload(fileName: String, baseDirectory: URL) throws -> String {
    guard !fileName.isEmpty,
          fileName == URL(fileURLWithPath: fileName).lastPathComponent else {
        throw PathValidationError.invalidFileName
    }

    // baseDirectory는 앱만 쓸 수 있는 디렉터리여야 합니다.
    let base = baseDirectory
        .resolvingSymlinksInPath()
        .standardizedFileURL
    let candidate = base
        .appendingPathComponent(fileName, isDirectory: false)
        .resolvingSymlinksInPath()
        .standardizedFileURL

    guard candidate.deletingLastPathComponent() == base else {
        throw PathValidationError.outsideBaseDirectory
    }

    return try String(contentsOf: candidate, encoding: .utf8)
}

설명:

  • 변경 전: 사용자 입력이 파일 경로 전체로 사용됩니다.
  • 변경 후: 단일 파일명만 허용하고 기준 디렉터리와 후보 경로의 심볼릭 링크를 해석한 뒤, 실제 부모 디렉터리가 기준 디렉터리와 같은 경우에만 읽습니다. 예시처럼 기준 디렉터리는 앱만 수정할 수 있어야 하며, 공격자가 검사 후 경로를 교체할 수 없도록 보호해야 합니다.

참조