이전 포스팅에서는 안전한 파일 업로드 기능을 구현하기 위해 보안성, 정확성, 안정성이라는 세 가지 관점에서 학습을 진행하기로 했습니다.

첫 번째로 보안성에 초점을 맞춰 OWASP의 File Upload Cheat Sheet를 살펴보려고 합니다.

OWASP는 웹 애플리케이션 보안에 관한 다양한 가이드와 자료를 제공하는 비영리 재단입니다. Cheat Sheet Series는 OWASP에서 개발자가 안전한 소프트웨어를 구현할 때 참고할 수 있는 실무 중심의 보안 지침을 정리한 자료입니다.

그중 File Upload Cheat Sheet에서는 파일 업로드 과정에서 발생할 수 있는 보안 위협과 이를 방지하기 위한 주요 원칙을 설명하고 있습니다.

참고


1. 파일 업로드에서 발생할 수 있는 보안 위협

파일 업로드는 외부에서 전달된 데이터를 서버가 받아들이는 기능입니다. 따라서 그만큼 공격의 대상이 되기도 쉽습니다.

OWASP에서는 파일 업로드와 관련된 보안 위협을 크게 악의적인 파일(Malicious Files)과 파일 조회 및 배포 과정의 보안 위협(Public File Retrieval)이라는 두 가지 유형으로 구분하여 설명하고 있습니다.

  • 악의적인 파일(Malicious Files): 업로드된 악의적인 파일이 서버에서 처리되는 과정에서 발생하는 보안 위협
  • 파일 조회 및 배포 과정의 보안 위협(Public File Retrieval): 업로드된 파일을 외부에 제공하는 과정에서 발생하는 보안 위협

결국 파일 업로드의 안전성을 확보하려면 파일을 받아들이는 과정뿐만 아니라, 저장된 파일을 외부에 제공하는 과정까지 고려해야 한다는 의미입니다.


1.1. 악의적인 파일(Malicious Files)

OWASP에서 악의적인 파일 업로드와 관련하여 설명하는 대표적인 보안 위협은 다음과 같습니다.

보안 위협 설명
파일 처리 프로그램의 취약점 악용 이미지나 문서 등의 파일을 처리하는 라이브러리의 취약점을 이용한 공격
피싱(Phishing) 악의적인 파일을 이용해 사용자를 속이거나 민감한 정보를 탈취
서비스 거부(DoS) 대용량 파일이나 압축 폭탄 등을 이용해 시스템 자원을 고갈
기존 파일 덮어쓰기 파일명이나 저장 경로를 조작하여 정상적인 기존 파일을 임의로 변경
클라이언트 측 공격 악성 스크립트 등이 포함된 파일을 통해 XSS 등의 공격 유발

위와 같은 보안 위협을 방지하려면 파일 업로드부터 검증, 저장, 처리에 이르는 전 과정에서 발생할 수 있는 위험성을 고려해야 합니다.

앞서 작성한 [학습기록] Java 개발자가 알아야 할 서비스 거부(DoS) 취약점: (2) 과도한 자원 소비의 위험성에서 작은 압축파일을 해제하는 과정에서 시스템 자원이 고갈될 수 있는 ZIP Bomb과 같은 서비스 거부(DoS) 취약점에 대해서 살펴본 적이 있습니다.

이처럼 이전에 학습했던 내용을 다른 주제와 연결하면서 지식이 조금씩 확장되고 있다는 사실을 느낄 수 있는 것 같습니다.


1.2. 파일 조회 및 배포 과정의 보안 위협(Public File Retrieval)

OWASP에서는 업로드된 파일을 외부에 공개하거나 다운로드할 수 있도록 제공하는 과정에서도 보안 위협이 발생할 수 있다고 설명합니다.

대표적인 보안 위협은 다음과 같습니다.

보안 위협 설명
비인가 파일 노출 공개 대상이 아닌 파일이 외부에 노출될 위험
서비스 거부(DoS) 대량의 다운로드 요청으로 서버나 네트워크 자원이 고갈될 위험
부적절한 콘텐츠 배포 불법적이거나 유해한 파일을 저장하고 배포하는 용도로 서비스가 악용될 위험

특히 서비스 거부(DoS)는 파일 업로드뿐만 아니라 다운로드 과정에서도 발생할 수 있습니다.

파일 다운로드는 요청 자체의 크기가 작더라도 응답으로 전송되는 파일의 크기는 상대적으로 클 수 있습니다. 따라서 공격자가 대량의 다운로드 요청을 반복하면 서버나 네트워크에 과도한 부하가 발생할 수 있습니다.

결국 안전한 파일 업로드를 구현하려면 파일을 업로드하고 저장하는 과정뿐만 아니라, 저장된 파일을 외부에 제공하는 과정에서 발생할 수 있는 위험성도 함께 고려해야 합니다.


2. 안전한 파일 업로드 기능 구현을 위한 보안 원칙

OWASP에서는 안전한 파일 업로드 기능을 구현하기 위해 지켜야 하는 다양한 보안 원칙을 설명하고 있습니다. 여기서 주목해야 할 것은 임의로 몇 가지 보안 원칙만 선택해서는 모든 위협에 대응할 수 없다는 점입니다.

예를 들어 파일 확장자를 검증하더라도 실제 파일의 내용이 조작되었을 수 있고, 파일 형식을 검증하더라도 저장 경로에 대한 접근 권한이 잘못 설정되어 있다면 여전히 보안 문제가 발생할 수 있습니다. 따라서 여러 보안 원칙을 함께 적용하여 개별 대책의 한계를 보완하는 심층 방어(Defense in Depth)가 중요합니다.

따라서 OWASP에서 설명하는 보안 원칙 중 일부만 임의로 선택하기보다는 각 보안 대책이 어떤 위협에 대응하기 위한 것인지 이해하고 적용 여부를 판단해야 합니다.

서비스의 특성과 위험 수준을 고려하여 적용할 보안 원칙을 결정해야 하며, 적용하지 않는 원칙에 대해서도 그 이유를 설명할 수 있어야 할 것입니다.


2.1. 파일 확장자 검증(Extension Validation)

OWASP에서는 파일 확장자 검증 방법으로 확장자 허용 목록(List Allowed Extensions)과 확장자 차단(Block Extensions)을 설명하고 있습니다.

확장자 허용 목록(List Allowed Extensions)

애플리케이션의 업무에 꼭 필요한 확장자만 허용하고, 나머지는 차단하는 방식입니다. 특히 업무에 필요한 파일 형식 중에서도 위험도가 가장 낮은 형식을 선택할 것을 권고합니다.

확장자 차단(Block Extensions)

서비스에 위험을 초래할 수 있는 확장자를 식별하여 차단하는 방식입니다. 하지만 위험한 확장자를 모두 식별하기 어렵고, 차단 목록에 포함되지 않은 다른 확장자를 이용해 검증을 우회할 수 있다는 한계가 있습니다. 따라서 OWASP에서는 특정 확장자만 차단하는 방식은 단독으로 사용하기에 취약한 보호 수단이라고 설명합니다.

결국 업무에 꼭 필요한 확장자만 허용하는 것을 기본으로 하고, 확장자 차단 방식은 필요에 따라 보완적으로 활용하는 것이 적절할 것 같습니다.


2.2. Content-Type 검증(Content-Type Validation)

Content-Type은 HTTP 요청에서 전달하는 파일의 형식 정보입니다. 예를 들어 JPEG 이미지라면 image/jpeg, PNG 이미지라면 image/png으로 표현합니다.

하지만 Content-Type은 클라이언트가 임의로 변경할 수 있기 때문에 신뢰할 수 없습니다.

OWASP에서는 Content-Type을 사용자가 의도하지 않은 형식의 파일을 업로드하는 것을 방지하기 위한 간단한 검증 수단으로 활용할 수 있지만, 보안 검증의 유일한 기준으로 사용해서는 안 된다고 설명하고 있습니다.


2.3. 파일 시그니처 검증(File Signature Validation)

파일 시그니처(File Signature)는 파일 내부의 특정 바이트 패턴을 이용하여 파일 형식을 식별하는 방법입니다. 예를 들어 PNG 파일은 일반적으로 89 50 4E 47 0D 0A 1A 0A라는 바이트 패턴으로 시작합니다.

파일 시그니처를 검증하면 확장자나 Content-Type과 달리 실제 파일의 내용을 기반으로 형식을 확인할 수 있습니다. 하지만 파일 시그니처 역시 조작할 수 있으며, 시그니처가 일치한다고 해서 파일 전체가 안전하다는 의미는 아닙니다.

OWASP에서는 파일 시그니처 검증은 비교적 쉽게 우회할 수 있으므로 다른 검증 방법과 함께 적용해야 한다고 설명합니다.


2.4. 파일명 안전성(Filename Safety)

사용자가 전달한 파일명을 그대로 사용하면 보안 문제가 발생할 수 있습니다. 파일명에 포함된 특수문자나 예약된 이름을 악용하여 의도하지 않은 파일을 생성하거나 기존 파일을 덮어쓸 수 있기 때문입니다.

OWASP에서는 이러한 위험을 방지하기 위해 UUID와 같이 서버에서 생성한 임의의 파일명을 사용하도록 권고합니다.

다만 업무상 원본 파일명을 사용해야 한다면 다음과 같은 검증이 필요합니다.

  • 파일명 길이 제한: 파일 시스템에서 허용하는 최대 길이를 고려하여 제한
  • 허용 문자 제한: 영문자, 숫자, 하이픈 등 허용할 문자만 사용하도록 제한
  • 특수한 파일명 제한: 숨김 파일이나 경로 조작에 악용될 수 있는 파일명 차단
  • 위험한 문자 제한: 파일 시스템이나 애플리케이션에서 특수하게 해석되는 문자 차단

특히 ../와 같은 경로 조작 문자열이 파일명에 포함되어 있다면 지정된 저장 경로를 벗어나 다른 파일에 접근하거나 덮어쓰는 문제가 발생할 수 있습니다.

결국 사용자가 전달한 파일명을 그대로 신뢰하지 않고, 서버에서 안전한 파일명을 생성하여 사용하는 것이 기본적인 보안 원칙이라고 이해할 수 있습니다.


2.5. 파일 내용 검증(File Content Validation)

파일의 확장자나 시그니처가 정상이라고 해서 파일의 내용까지 안전하다고 판단할 수는 없습니다. 파일 내부에 악의적이거나 부적절한 데이터가 포함되어 있을 수 있기 때문입니다.

OWASP에서는 파일 형식별 특성을 고려하여 적절한 내용 검증 방법을 적용할 것을 권고하고 있습니다.

파일 형식 검증 및 대응 방법
이미지 이미지를 디코딩한 후 허용된 형식으로 재인코딩하고 불필요한 메타데이터 제거
Microsoft Office 문서 Apache POI 등의 라이브러리를 활용하여 문서 구조와 내용 검증
ZIP 압축파일 다양한 형식의 파일이 포함될 수 있고 공격 위험이 많으므로 가급적 허용하지 않을 것을 권고

이외에도 악성코드 검사를 위한 백신이나 샌드박스 활용, 외부에 공개하기 전 파일 검토 등의 보안 대책을 고려할 수 있습니다.

다만 파일 내용을 검증하거나 재인코딩하는 과정에서도 보안 취약점이 발생할 수 있다는 점에 주의해야 합니다. 파일을 처리하는 라이브러리 역시 외부에서 전달된 데이터를 처리하기 때문입니다.

따라서 파일 처리 라이브러리의 보안 취약점을 관리하고, 처리 과정에서 사용하는 시스템 자원도 제한해야 합니다.

결국 파일 내용 검증은 단순히 파일 형식이 올바른지 확인하는 것을 넘어, 해당 파일을 안전하게 처리하고 이용할 수 있는지 검토하는 과정이라고 이해할 수 있습니다.


2.6. 파일 저장 위치(File Storage Location)

파일을 어디에 저장하는지도 중요한 보안 요소입니다. 업로드된 파일의 저장 위치에 따라 외부 접근 가능 여부와 보안 위협이 달라질 수 있기 때문입니다.

OWASP에서는 보안 및 업무 요구사항을 고려하여 파일 저장 위치를 결정할 것을 권고하며, 다음과 같은 우선순위를 제시하고 있습니다.

우선순위 저장 방식 설명
1 별도 서버에 저장 애플리케이션 서버와 파일 저장 서버를 분리하여 보안 위험을 격리
2 웹 루트(Web Root) 외부에 저장 웹 서버를 통한 직접 접근을 제한
3 웹 루트 내부에 저장 불가피한 경우 엄격한 파일 접근 및 쓰기 권한 통제

여기서 웹 루트(Web Root)는 웹 서버가 외부 요청에 대해 정적 파일을 제공하는 기본 디렉터리를 의미합니다.

업로드된 파일을 웹 루트 내부에 저장하면 웹 서버 설정에 따라 외부에서 직접 접근하거나 파일이 실행될 위험이 있습니다.

따라서 애플리케이션과 파일 저장 환경을 분리하고, 업로드된 파일에 대한 외부 접근을 적절히 통제하는 것이 중요합니다.

OWASP에서는 데이터베이스에 파일을 저장하는 방법도 설명하고 있지만, 성능과 저장 용량, 백업 및 보안 문제 등을 함께 고려해야 한다고 안내합니다.


2.7. 사용자 권한(User Permissions)

OWASP에서는 파일 업로드 기능을 사용하기 전에 사용자 인증(Authentication)과 인가(Authorization)를 검증할 것을 권고하고 있습니다.

인증(Authentication)

파일을 업로드하는 사용자가 누구인지 식별하는 과정입니다. 사용자를 식별할 수 있어야 사용자별 업로드 권한이나 사용량 등을 제한할 수 있습니다.

인가(Authorization)

인증된 사용자가 파일에 접근하거나 수정할 수 있는 권한을 가지고 있는지 확인하는 과정입니다.

예를 들어 관리자 시스템에 로그인한 사용자라고 해서 모든 파일을 업로드하거나 수정할 수 있는 것은 아닙니다. 사용자마다 담당 업무와 권한이 다를 수 있기 때문입니다.

따라서 사용자를 인증하는 것뿐만 아니라, 해당 사용자가 요청한 파일 작업을 수행할 권한이 있는지도 검증해야 합니다.


2.8. 파일 시스템 권한(Filesystem Permissions)

OWASP에서는 파일 시스템의 접근 권한을 설정할 때 최소 권한 원칙(Principle of Least Privilege)을 적용할 것을 권고합니다.

최소 권한 원칙이란 사용자나 프로세스에 업무 수행에 필요한 최소한의 권한만 부여하는 보안 원칙입니다.

파일 시스템에서도 다음과 같은 사항을 고려해야 합니다.

  • 읽기 권한(Read): 허가된 시스템 사용자나 프로세스만 파일을 읽을 수 있도록 제한
  • 쓰기 권한(Write): 파일을 생성하거나 수정해야 하는 사용자나 프로세스에만 부여
  • 실행 권한(Execute): 파일 실행이 반드시 필요한 경우에만 부여

예를 들어 이미지 저장 서비스에서 업로드된 이미지는 저장하고 조회하는 용도로 사용되므로 실행 권한을 부여할 필요가 없습니다.

결국 파일을 저장하는 것뿐만 아니라, 저장된 파일에 누가 접근할 수 있고 어떤 작업을 수행할 수 있는지 제한하는 것이 중요합니다.


2.9. 업로드 및 다운로드 제한(Upload and Download Limits)

OWASP에서는 시스템 자원을 보호하기 위해 업로드 파일의 크기와 다운로드 요청을 제한할 것을 권고합니다.

업로드 크기 제한(Upload Limits)

업로드할 수 있는 파일의 최대 크기를 제한하여 저장 공간이 고갈되는 것을 방지해야 합니다.

특히 압축파일을 해제하거나 파일을 추가로 처리하는 경우에는 원본 파일 크기뿐만 아니라 처리 후의 크기도 고려해야 합니다. 작은 압축파일이라도 압축 해제 후 크기가 급격히 증가할 수 있기 때문입니다.

다운로드 요청 제한(Download Limits)

업로드된 파일을 외부에 제공하는 경우에는 다운로드 요청에 대한 적절한 제한이 필요합니다.

공격자가 대량의 다운로드 요청을 발생시키면 서버와 네트워크 자원이 과도하게 소비되어 서비스 거부(DoS)로 이어질 수 있기 때문입니다.

결국 파일 업로드와 다운로드 과정에서 사용되는 시스템 자원을 적절히 제한하여 서비스의 가용성을 보호하는 것이 중요합니다.


2.10. 기타 보안 고려사항

OWASP에서는 앞서 살펴본 보안 원칙 외에도 다음과 같은 보안 대책을 권고하고 있습니다.

보안 대책 설명
CSRF 방어 사용자의 인증 상태를 악용한 의도하지 않은 파일 업로드 요청 방지
악성코드 검사 백신이나 샌드박스를 활용하여 악성 파일 탐지
CDR(Content Disarm & Reconstruction) PDF나 Office 문서 등의 위험한 요소를 제거하고 파일을 재구성
라이브러리 보안 관리 파일 처리 라이브러리의 안전한 설정과 보안 업데이트 유지

이러한 보안 대책 역시 서비스에서 허용하는 파일 형식과 운영환경을 고려하여 적용 여부를 판단해야 합니다.


3. OWASP 가이드를 통해 알게 된 점

OWASP의 File Upload Cheat Sheet를 살펴보면서 안전한 파일 업로드 기능을 구현하기 위해 생각보다 다양한 보안 요소를 고려해야 한다는 것을 알 수 있었습니다.

특히 파일 자체를 검증하는 것뿐만 아니라 저장 위치, 접근 권한, 외부 배포 과정까지 고려해야 한다는 점이 인상적이었습니다.

또한 개별 보안 대책에는 각각 한계가 있으므로, 여러 대책을 함께 적용하는 심층 방어가 중요하다는 것도 다시 확인할 수 있었습니다.

결국 안전한 파일 업로드 기능을 구현하려면 각 보안 대책이 어떤 위협에 대응하는지 이해하고, 이를 어디에서 어떻게 적용할 것인지 종합적으로 검토해야 한다는 것을 알 수 있었습니다.


4. 다음 포스팅

다음 포스팅에서는 KISA의 소프트웨어 개발보안 가이드를 통해 파일 업로드와 관련된 보안 취약점과 대응 방법을 살펴보겠습니다.

또한 앞서 학습한 OWASP의 권고사항과 비교하여 어떤 공통점과 차이점이 있는지도 알아보겠습니다.