--- 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 요약: (미작성)