파일 유형 분류하기 mimetype과 Content-Type

최예린·2025년 4월 3일

JavaScript

목록 보기
8/8

파일 유형 분류하기

Mimetype ?

: (Multipurpose Internet Mail Extensions Type)
인터넷에서 파일 형식을 식별하는 표준 방식

  • 일반적으로 type/subtype 형식으로 표현됨
text/html (HTML 문서)
image/png (PNG 이미지)
application/json (JSON 데이터)
  • HTTP, 이메일, 파일 확장자 매칭 등에 사용됨

Content-Type ?

:HTTP에서 사용되는 헤더 필드로, 응답 본문의 MIME 타입을 지정

클라이언트(브라우저 등)가 데이터를 해석하는 방법을 결정하는 데 사용

Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8

작업 배경

  • 어떤 유저가 avif 파일을 확장자 변조 후 업로드했다. avif 파일을 jpeg으로 인식하게 되었고, 파일 유형을 잘못 파악했기 때문에문제가 발생했다.
  • mimetype값을 파일의 버퍼값을 기반으로 계산하면 위와 같은 확장자 변조 문제를 해결할 수 있다.

Mimetype을 구하는 방법

1. Content-Type 분석

문제상황. 브라우저가 잘못된 Content-Type을 보냄

<input type="file">

위 코드를 사용할 때 브라우저가 mimetype을 자동으로 설정하는데, AVIF가 정확히 지원되지 않으면 JPEG으로 처리할 가능성이 있다.

우리는 NestJs 공식문서에서 제안한 방식대로 파일을 업로드받고 있었고


@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}

Express.Multer.File.mimetype에는 잘못된 mimetype이 들어있었다. 이게 문제가 되어서 magic number로 구분하는 방식을 서치하게 된것이다.


2. Magic Number 분석

  • Magic Number(File Signature) 란?
    : 파일 시그니처는 파일의 내용을 식별하거나 검증하는 데 사용되는 데이터이다. 이러한 시그니처는 매직 넘버 또는 매직 바이트 라고도 하며 , 일반적으로 파일 시작 부분에 추가된다.

Magic Number를 분석하는 함수 직접 구현

위의 링크에 들어가면 파일 확장자 별로 바이트(=magic number)가 정리되어있다.

파일의 버퍼에

0xFF, 0xD8, 0xFF

가 포함되어있으면 그 파일을 jpeg으로 판단할 수 있다.

몇가지 파일 유형 검사만 필요한 경우에는 직접 구현하는것이
외부 라이브러리의 의존성을 낮춰 장점이 될 수 있으나

파일 유형도 다양하고 예외의 경우가 많기때문에 사실은 라이브러리를 사용하는 것을 추천한다.

👍 file-type 라이브러리 사용

  • 버퍼로부터 mimetype 구하기
import {fileTypeFromBuffer} from 'file-type';

await fileTypeFromBuffer(buffer);

사용법이 굉장히 간단하고 입력값으로 버퍼와 파일을 모두 지원한다.

mime-types 라이브러리도 테스트해봤는데 위에서 언급한 확장자 변조 파일을(.heic) jpeg으로 판단했다.

  • file-type는 이번에 처음사용해봤는데 npm 다운로드 수를 보면 믿을만 한것 같다.
  • (레포 구경하다가 이 패키지 만든 사람이 awesome 만든사람이랑 동일인물인걸 알게됐다.)

사용법은 너무나도 간단했으나 패키지 설치과정에서 문제가 생겼다.

  • ESM 전용 패키지
npm file-type Error: No "exports" main defined

우리 프로젝트는 기존에 NestJs commonJs 방식을 사용하고 있었기때문에
해당 패키지를 설치하니 다음과 같은 에러가 발생했다.

⭕️ESM 방식에서는 CJS방식의 모듈을 사용할수있지만
❌CJS 방식에서는 ESM방식의 모듈을 사용할 수 없었다.

file-type 레포의 이슈에서 해결방법을 찾기는 했으나 우리의 상황에서는 ESM으로 전환해도 큰 문제가 없다고 생각해 업그레이드 했다.

(참고로 저 에러메시지만 쳐도 file-type이 자동완성으로 뜰 정도였다ㅋㅋㅠㅠ)

profile
경북대학교 글로벌소프트웨어융합전공/미디어아트연계전공

0개의 댓글