한국어
AI 버전
회사 소개 AI 시대의 시스템 개발 블로그 문의 AI 페이지

BLOG

요청 한 통에 서버가 멈춘다? Multer 취약점을 방치하면 안 되는 이유

Node.js/Express에서 파일 업로드를 구현했다면 거의 모두가 쓰는 Multer. 사실 1.x 계열에서는 2025〜2026년에 걸쳐 HIGH 등급 취약점 7건이 연달아 공개됐고, 모두 2.x에서 수정되었다. 그 구조와 대응을 친숙한 비유로 풀어본다.

#Node.js#Express#Multer#보안#취약점

이미지 업로드를 구현할 때마다 손이 가는 multer. 그런데 2025년 이후 HIGH severity 취약점 7건이 연달아 공개됐다. “취약점이라고? 어렵겠는데…”라는 생각이 들 수도 있지만, 방치하면 어느 날 갑자기 서비스가 통째로 멈출 수도 있다.

이 글에서는 주니어 엔지니어를 위해 Multer가 무슨 일을 하는지, 이번 문제의 정체는 무엇인지, 그리고 5분이면 끝나는 대응법까지 차근차근 풀어본다.

업로드를 분류하는 직원과 경고 표지

① Multer는 도대체 무슨 일을 해주는 걸까?

Express에서 파일 업로드를 구현해 봤다면 multer는 무조건 거쳐 갔을 것이다. 하지만 막상 “뭘 해결해 주는 거야?”라는 질문에는 답하기가 의외로 어렵지 않은가?

브라우저가 <input type="file">로 보낸 데이터는 HTTP 요청 안에 거대한 텍스트 덩어리로 들어 있다. Content-Type: multipart/form-data라는 독특한 포맷으로, 여러 파일과 폼 필드가 한데 이어 붙은 상태다.

이 상태로는 Node.js에서 파일로 다룰 수 없다. Multer는 그 “덩어리”에서 이미지나 PDF를 잘라내 디스크에 저장하고, req.file / req.files라는 쓰기 좋은 형태로 정리해 주는 “분류 담당 사무직원” 같은 존재다.

브라우저 → Multer → Express에서 다룰 수 있는 형태로 변환되는 흐름

import multer from "multer";

const upload = multer({ dest: "uploads/" });

app.post("/upload", upload.single("photo"), (req, res) => {
  // req.file에 저장 경로와 파일 정보가 이미 들어 있다
  res.json({ saved: req.file.path });
});

단 몇 줄로 파일 업로드가 완성된다. 그건 사무직원이 뒤에서 묵묵히 서류를 분류해 주고 있기 때문이다.

② 이번 취약점, 친숙한 비유로

평소엔 이런 식이다:

너: “이 multipart 요청, 이미지랑 텍스트로 분류해서 저장해 둬.”

사무직원(Multer): “OK, 3밀리초면 돼.”

이번 취약점은 “사무직원을 의도적으로 패닉에 빠뜨리는 요청 보내는 법” 이 여러 가지 발견됐다는 이야기다.

평소엔 깔끔히 처리, 공격받으면 직원이 패닉에 빠지고 처리 대기가 쌓인다

구체적으로 공격자가 다음과 같은 요청을 보내면…

  • 빈 필드명이 들어 있는 이상한 서류 → 직원 패닉 → 서버 프로세스째로 다운 (CVE-2025-48997)
  • 업로드 도중에 연결을 끊는 동작을 대량으로 반복 → 직원이 치우지 못한 서류가 책상 위에 쌓임 → 메모리와 FD 고갈 (CVE-2025-47935, CVE-2026-2359)
  • 중첩이 비정상적으로 깊은 서류를 보냄 → 직원이 “페이지 넘기기 지옥”에 빠지면서 책상째 폭발 (재귀 스택 오버플로우, CVE-2026-3520)

즉, 이번 사안은 “데이터가 새는” 쪽보다 “서비스가 통째로 멈추는” 타입의 취약점 (DoS, Denial of Service) 이 핵심이다. 악의적인 요청 한 통만으로 Node.js 프로세스가 크래시 나는 것도 있다.

③ 영향: 데이터 유출보다 무서운 “서비스 정지”

“데이터가 새는 것도 아닌데 그게 그렇게 큰일이야?”라고 생각할 수도 있다. 하지만 실무적으로는 이쪽이 훨씬 더 고통스럽다.

  • 새벽 2시에 서버가 다운 → 모니터링 알람 → 엔지니어가 깨워짐
  • 서비스가 멈춰 있는 동안 매출은 0 → 한 시간 다운되면 EC 사이트 기준 수십만 원이 그냥 증발
  • 복구 후 사후 대응 → 고객 사과, 원인 분석, 포스트모템 작성
  • 작은 공격이 반복되어 메모리가 고갈 → 서서히 무거워지면서 누구 탓인지도 모른 채 현장이 지쳐 감

요컨대 “취약점을 방치한다 = 어느 날 갑자기 새벽에 깨어날 확률을 높인다”라는 뜻이다. 무섭지 않은가.

④ 공개된 7건의 취약점 (1차 정보 정리)

참고로 2025〜2026년에 공개된 Multer의 HIGH severity 취약점을 시간순으로 정리해 둔다. 링크는 모두 GitHub Security Advisory(1차 정보원)다.

공개일CVE종류영향 버전수정
2025-05-19CVE-2025-47944미처리 예외로 크래시<2.0.02.0.0
2025-05-19CVE-2025-47935메모리/FD 누수<2.0.02.0.0
2025-06-03CVE-2025-48997빈 필드명에 의한 크래시<2.0.12.0.1
2025-07-17CVE-2025-7338비정상 요청에 의한 크래시<2.0.22.0.2
2026-02-27CVE-2026-2359연결 끊김 시 리소스 미해제<2.1.02.1.0
2026-02-27CVE-2026-3304클린업 누락<2.1.02.1.0
2026-03-04CVE-2026-3520깊은 중첩으로 재귀 폭주<2.1.12.1.1

CVSS는 대체로 7.5〜8.7 (HIGH) 사이. multer 1.x (1.4.5-lts.2 포함)는 사실상 전멸이라고 봐도 된다.

⑤ 대응: 당신의 코드를 살리는 3단계

5분이면 끝난다.

Step 1. 현재 버전 확인

npm ls multer
# 또는
cat package.json | grep multer

1.x 계열(1.4.x 포함)이라면 취약점 대상이다.

Step 2. 최신 2.x로 업데이트

npm install multer@latest
# pnpm이라면
pnpm add multer@latest
# yarn이라면
yarn add multer@latest

이걸로 multer@2.1.1 이상이 설치된다(집필 시점 기준).

Step 3. 업데이트 후 동작 확인

Multer 1.x → 2.x의 API는 기본적으로 호환되지만, 몇 가지 변경점이 있다:

  • multer.diskStorage / multer.memoryStorage는 그대로 쓸 수 있다
  • 일부 deprecated 콜백이 제거됐다
  • 파일 필터의 에러 핸들링이 조금 더 엄격해졌다

간단한 동작 확인과 테스트를 돌려서 에러가 없으면 끝:

npm audit
# "found 0 vulnerabilities"가 이상적

GitHub 리포지토리에서 Dependabot을 활성화해 두면 이런 취약점이 공개됐을 때 자동으로 PR을 올려 주니, 아직 안 켜 놨다면 설정해 두기를 권한다.

마무리

취약점은 누구의 잘못도 아니다. OSS 메인테이너도 사람이고, 공격 기법도 매일 진화한다. 중요한 건 “정기적으로 업데이트를 흡수해 가는 운영”을 프로젝트에 심는 것. 이게 주니어와 프로 엔지니어를 가르는 분기점이기도 하다.

npm install multer@latest 한 줄로, 새벽에 깨워질 확률이 확 줄어든다. 지금 바로 package.json을 열어 보자.


Refs (1차 정보):

CONTACT

문의

편하게 문의해 주세요.