Files
llm-wiki/raw/official-docs/owasp-file-upload-cheat-sheet.md
T

102 lines
9.1 KiB
Markdown

---
title: OWASP File Upload Cheat Sheet — extension/content-type validation + storage isolation
source_type: official-doc
url: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
archive_url:
status: raw
confidence: high
related_branches: [feature-file-resource-handling-contract, feature-security-operational-baseline]
related_projects: [ca-skeleton-operational-contract]
tags: [ca-security, file-upload, owasp, extension-allowlist, content-type, storage-isolation, official-doc]
created: 2026-05-27
last_reviewed: 2026-05-27
---
# OWASP File Upload Cheat Sheet
> Layer: `raw/official-docs/` — OWASP Foundation 발행 file upload security cheat sheet. ca-tmpl file resource handling contract D5 (file upload validation pipeline) 의 운영 원칙 reference.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-file-resource-handling-contract]] | D5 (file upload validation pipeline — extension allowlist, content-type 신뢰 금지, UUID 파일명, webroot 밖 저장, size limit, AV 스캔) 의 원칙별 1차 근거 |
| [[raw/branch-notes/feature-security-operational-baseline]] | upload endpoint 의 deny-by-default 원칙과 antivirus / sandboxing 운영 권고 근거 |
## 컨텍스트 / 왜 저장했는지
ca-tmpl file resource handling contract 에서 "왜 Content-Type 헤더를 신뢰하면 안 되는가", "왜 원본 파일명을 보존하지 않고 UUID 로 rename 해야 하는가", "왜 파일을 webroot 밖에 저장해야 하는가" 결정의 1차 운영 원칙 출처. OWASP cheatsheet 는 표준 아니지만 광범위한 커뮤니티 합의를 가짐.
## 출처 / Source
- 원본 URL: https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
- 아카이브 URL: (미수집)
- 저자 / 조직: OWASP Foundation (Cheat Sheet Series — 커뮤니티 합의 + foundation 발행)
- 발행일: rolling docs
- 마지막 확인일: 2026-05-27 (WebFetch verbatim 확인)
## 핵심 인용 / Key quotes (verbatim, captured 2026-05-27)
> [§Extension Validation] "List allowed extensions. Only allow safe and critical extensions for business functionality"
> [§Content-Type Validation] "The Content-Type for uploaded files is provided by the user, and as such cannot be trusted, as it is trivial to spoof."
> [§Filename Safety] "Creating a random string as a filename, such as generating a UUID/GUID, is essential."
> [§File Storage Location] "Store the files on a different host, which allows for complete segregation of duties between the application serving the user, and the host handling file uploads and their storage."
> [§File Storage Location] "Store the files outside the webroot, where only administrative access is allowed."
> [§Upload and Download Limits] "The application should set proper size limits for the upload service in order to protect the file storage capacity."
> [§Malicious Files] "Run the file through an antivirus or a sandbox if available to validate that it doesn't contain malicious data."
> [§Filesystem Permissions] "Set the files permissions on the principle of least privilege."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| OWASP-FUP-C1 | 업로드 파일 extension 은 **allowlist** 로 관리 — business functionality 에 필요한 safe 한 extension 만 허용 | [§Extension Validation] "List allowed extensions. Only allow safe and critical extensions for business functionality" | `official-reference` (OWASP cheatsheet — 표준 아님) | extension allowlist (예: jpg/png/pdf 만) 결정 | extension 검증만으로 충분하다는 뜻은 아님 — content-type / magic byte 검증 별도 필요 |
| OWASP-FUP-C2 | client 가 보낸 **Content-Type 헤더는 신뢰할 수 없음** — spoof 가 trivial 함 | [§Content-Type Validation] "The Content-Type for uploaded files is provided by the user, and as such cannot be trusted, as it is trivial to spoof." | `official-reference` | Content-Type 만으로 type 판정하는 검증 로직 금지 결정 | server-side magic byte 검증 (Apache Tika 등) 이 의무라는 본 인용은 없음 — 단, "신뢰 못 함" 으로 사실상 require |
| OWASP-FUP-C3 | 파일명은 **random string (UUID/GUID)** 으로 생성하는 것이 **essential** | [§Filename Safety] "Creating a random string as a filename, such as generating a UUID/GUID, is essential." | `official-reference` | 원본 파일명을 저장 키로 사용하지 않고 UUID 로 rename 하는 결정 | 원본 파일명을 metadata 로도 보존하면 안 된다는 뜻은 아님 — 저장 키와 표시 이름 분리는 별개 |
| OWASP-FUP-C4 | 파일은 application 호스트와 **분리된 host** 에 저장하여 application 서버와 storage 서버의 책임을 완전히 분리 | [§File Storage Location] "Store the files on a different host, which allows for complete segregation of duties between the application serving the user, and the host handling file uploads and their storage." | `official-reference` | S3 / dedicated file server 분리 결정 | 모든 application 이 별도 host 를 가져야 한다는 뜻은 아님 — risk-based 권고 |
| OWASP-FUP-C5 | 파일은 **webroot 밖** 에 저장하여 administrative access 만 허용 | [§File Storage Location] "Store the files outside the webroot, where only administrative access is allowed." | `official-reference` | static file serving path 밖에 업로드 저장 결정 | webroot 밖 저장 후 어떻게 client 에게 download 제공하는지는 본 인용 범위 밖 — pre-signed URL 또는 application proxy 등 별도 |
| OWASP-FUP-C6 | application 은 file storage capacity 보호를 위해 **size limit** 을 설정해야 함 (`should`) | [§Upload and Download Limits] "The application should set proper size limits for the upload service in order to protect the file storage capacity." | `official-reference` | multipart `maxFileSize` / `maxRequestSize` 결정 | 구체적 size 값 권고는 본 인용에 없음 — application 별 판단 |
| OWASP-FUP-C7 | 가능하면 antivirus 또는 sandbox 로 파일을 검사하여 malicious data 가 없는지 확인 | [§Malicious Files] "Run the file through an antivirus or a sandbox if available to validate that it doesn't contain malicious data." | `official-reference` | ClamAV / sandbox 검사 파이프라인 결정 | AV 검사가 모든 attack 을 차단한다는 뜻은 아님 — zero-day / polymorphic malware 우회 가능 |
| OWASP-FUP-C8 | 파일 권한은 **least privilege** 원칙으로 설정 | [§Filesystem Permissions] "Set the files permissions on the principle of least privilege." | `official-reference` | 업로드 디렉토리의 read/write/execute 권한 최소화 (예: 0600, no execute) | 구체적 UNIX permission 값은 OS / 환경 별 — 본 인용은 원칙만 |
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것** (2026-05-27 WebFetch verbatim 확인):
- `OWASP-FUP-C1` ~ `C8`: extension allowlist, content-type 신뢰 금지, UUID 파일명, host 분리, webroot 밖 저장, size limit, AV 스캔, least privilege permission
- **이 자료가 증명하지 않는 것**:
- 구체적 magic byte 검증 라이브러리 권고 (Apache Tika, file(1) 등) — 본 cheatsheet 는 원칙만
- pre-signed URL vs application proxy download 중 어느 쪽이 우수한지 — 본 인용 범위 밖
- S3 / GCS / Azure Blob 같은 특정 object storage 권고 — vendor neutral cheatsheet
- antivirus 가 모든 malware 를 차단한다는 보장 — `C7` 는 "if available" 권고
- OWASP cheatsheet 는 **권고이며 강제 표준이 아님**. RFC / 벤더 doc 보다 normative 권위 낮음.
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 의 실제 file storage backend (local FS vs S3 vs MinIO) 별 권한 설정 매핑
- magic byte 검증 라이브러리 선정 (Apache Tika vs java-jmagic vs custom)
- antivirus 통합 방식 (ClamAV daemon vs cloud AV API)
- extension allowlist 와 magic byte mismatch 발견 시 처리 정책 (reject vs quarantine)
## 메모 / Notes
- **다른 OWASP 자료와의 관계**: 본 cheatsheet 는 path traversal 도 부분적으로 다루지만 상세는 별도 path traversal 자료 ([[raw/official-docs/owasp-path-traversal]]) 참조.
- **OWASP ASVS V12** (File and Resources) 가 normative 권위 더 높음 — 본 cheatsheet 를 ASVS 와 함께 참조하면 더 강함.
- **ca-tmpl 운영 함의**: `C2` (content-type 신뢰 금지) + `C3` (UUID 파일명) + `C5` (webroot 밖) 세 가지가 ca-tmpl 의 최소 baseline 으로 적합. AV 스캔 (`C7`) 은 internal-first skeleton 에서는 옵션, public-facing 시점에 의무화 권장.
## Related / 관련
- 같은 주제 다른 official-doc:
- [[raw/official-docs/owasp-path-traversal]] (path traversal 상세)
- OWASP ASVS V12 File and Resources — 별도 raw 작성 후보
- 인용하는 branch:
- [[raw/branch-notes/feature-file-resource-handling-contract]]
- [[raw/branch-notes/feature-security-operational-baseline]]
- 인용하는 project:
- [[raw/project-notes/ca-skeleton-operational-contract]]
- 인용한 wiki 요약: (미작성)