BLOG
요청 한 통에 서버가 멈춘다? Multer 취약점을 방치하면 안 되는 이유
Node.js/Express에서 파일 업로드를 구현했다면 거의 모두가 쓰는 Multer. 사실 1.x 계열에서는 2025〜2026년에 걸쳐 HIGH 등급 취약점 7건이 연달아 공개됐고, 모두 2.x에서 수정되었다. 그 구조와 대응을 친숙한 비유로 풀어본다.
이미지 업로드를 구현할 때마다 손이 가는 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라는 쓰기 좋은 형태로 정리해 주는 “분류 담당 사무직원” 같은 존재다.

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-19 | CVE-2025-47944 | 미처리 예외로 크래시 | <2.0.0 | 2.0.0 |
| 2025-05-19 | CVE-2025-47935 | 메모리/FD 누수 | <2.0.0 | 2.0.0 |
| 2025-06-03 | CVE-2025-48997 | 빈 필드명에 의한 크래시 | <2.0.1 | 2.0.1 |
| 2025-07-17 | CVE-2025-7338 | 비정상 요청에 의한 크래시 | <2.0.2 | 2.0.2 |
| 2026-02-27 | CVE-2026-2359 | 연결 끊김 시 리소스 미해제 | <2.1.0 | 2.1.0 |
| 2026-02-27 | CVE-2026-3304 | 클린업 누락 | <2.1.0 | 2.1.0 |
| 2026-03-04 | CVE-2026-3520 | 깊은 중첩으로 재귀 폭주 | <2.1.1 | 2.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차 정보):