# 요청 한 통에 서버가 멈춘다? Multer 취약점을 방치하면 안 되는 이유 > Node.js/Express에서 파일 업로드를 구현했다면 거의 모두가 쓰는 Multer. 사실 1.x 계열에서는 2025〜2026년에 걸쳐 HIGH 등급 취약점 7건이 연달아 공개됐고, 모두 2.x에서 수정되었다. 그 구조와 대응을 친숙한 비유로 풀어본다. Date: 2026-04-28 Tags: Node.js, Express, Multer, 보안, 취약점 --- 이미지 업로드를 구현할 때마다 손이 가는 `multer`. 그런데 2025년 이후 **HIGH severity 취약점 7건**이 연달아 공개됐다. "취약점이라고? 어렵겠는데…"라는 생각이 들 수도 있지만, 방치하면 어느 날 갑자기 **서비스가 통째로 멈출 수도** 있다. 이 글에서는 주니어 엔지니어를 위해 Multer가 무슨 일을 하는지, 이번 문제의 정체는 무엇인지, 그리고 5분이면 끝나는 대응법까지 차근차근 풀어본다. ![업로드를 분류하는 직원과 경고 표지](https://img.wiredxeco.com/wiredxeco/multer-vulnerabilities-2025-2026/hero.png) ## ① Multer는 도대체 무슨 일을 해주는 걸까? Express에서 파일 업로드를 구현해 봤다면 `multer`는 무조건 거쳐 갔을 것이다. 하지만 막상 "뭘 해결해 주는 거야?"라는 질문에는 답하기가 의외로 어렵지 않은가? 브라우저가 ``로 보낸 데이터는 HTTP 요청 안에 **거대한 텍스트 덩어리**로 들어 있다. `Content-Type: multipart/form-data`라는 독특한 포맷으로, 여러 파일과 폼 필드가 한데 이어 붙은 상태다. 이 상태로는 Node.js에서 파일로 다룰 수 없다. **Multer는 그 "덩어리"에서 이미지나 PDF를 잘라내 디스크에 저장하고, `req.file` / `req.files`라는 쓰기 좋은 형태로 정리해 주는 "분류 담당 사무직원"** 같은 존재다. ![브라우저 → Multer → Express에서 다룰 수 있는 형태로 변환되는 흐름](https://img.wiredxeco.com/wiredxeco/multer-vulnerabilities-2025-2026/role.png) ```js 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밀리초면 돼." 이번 취약점은 **"사무직원을 의도적으로 패닉에 빠뜨리는 요청 보내는 법"** 이 여러 가지 발견됐다는 이야기다. ![평소엔 깔끔히 처리, 공격받으면 직원이 패닉에 빠지고 처리 대기가 쌓인다](https://img.wiredxeco.com/wiredxeco/multer-vulnerabilities-2025-2026/attack.png) 구체적으로 공격자가 다음과 같은 요청을 보내면… - **빈 필드명**이 들어 있는 이상한 서류 → 직원 패닉 → 서버 프로세스째로 다운 ([CVE-2025-48997](https://github.com/expressjs/multer/security/advisories/GHSA-g5hg-p3ph-g8qg)) - 업로드 **도중에 연결을 끊는** 동작을 대량으로 반복 → 직원이 치우지 못한 서류가 책상 위에 쌓임 → 메모리와 FD 고갈 ([CVE-2025-47935](https://github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5), [CVE-2026-2359](https://github.com/expressjs/multer/security/advisories/GHSA-v52c-386h-88mc)) - **중첩이 비정상적으로 깊은** 서류를 보냄 → 직원이 "페이지 넘기기 지옥"에 빠지면서 책상째 폭발 (재귀 스택 오버플로우, [CVE-2026-3520](https://github.com/expressjs/multer/security/advisories/GHSA-5528-5vmv-3xc2)) 즉, 이번 사안은 **"데이터가 새는" 쪽보다 "서비스가 통째로 멈추는" 타입의 취약점 (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](https://github.com/expressjs/multer/security/advisories/GHSA-4pg4-qvpc-4q3h) | 미처리 예외로 크래시 | <2.0.0 | 2.0.0 | | 2025-05-19 | [CVE-2025-47935](https://github.com/expressjs/multer/security/advisories/GHSA-44fp-w29j-9vj5) | 메모리/FD 누수 | <2.0.0 | 2.0.0 | | 2025-06-03 | [CVE-2025-48997](https://github.com/expressjs/multer/security/advisories/GHSA-g5hg-p3ph-g8qg) | 빈 필드명에 의한 크래시 | <2.0.1 | 2.0.1 | | 2025-07-17 | [CVE-2025-7338](https://github.com/expressjs/multer/security/advisories/GHSA-fjgf-rc76-4x9p) | 비정상 요청에 의한 크래시 | <2.0.2 | 2.0.2 | | 2026-02-27 | [CVE-2026-2359](https://github.com/expressjs/multer/security/advisories/GHSA-v52c-386h-88mc) | 연결 끊김 시 리소스 미해제 | <2.1.0 | 2.1.0 | | 2026-02-27 | [CVE-2026-3304](https://github.com/expressjs/multer/security/advisories/GHSA-xf7r-hgr6-v32p) | 클린업 누락 | <2.1.0 | 2.1.0 | | 2026-03-04 | [CVE-2026-3520](https://github.com/expressjs/multer/security/advisories/GHSA-5528-5vmv-3xc2) | 깊은 중첩으로 재귀 폭주 | <2.1.1 | 2.1.1 | CVSS는 대체로 7.5〜8.7 (HIGH) 사이. multer 1.x (`1.4.5-lts.2` 포함)는 **사실상 전멸**이라고 봐도 된다. ## ⑤ 대응: 당신의 코드를 살리는 3단계 5분이면 끝난다. ### Step 1. 현재 버전 확인 ```bash npm ls multer # 또는 cat package.json | grep multer ``` `1.x` 계열(`1.4.x` 포함)이라면 취약점 대상이다. ### Step 2. 최신 2.x로 업데이트 ```bash 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 콜백이 제거됐다 - 파일 필터의 에러 핸들링이 조금 더 엄격해졌다 간단한 동작 확인과 테스트를 돌려서 에러가 없으면 끝: ```bash npm audit # "found 0 vulnerabilities"가 이상적 ``` GitHub 리포지토리에서 Dependabot을 활성화해 두면 이런 취약점이 공개됐을 때 자동으로 PR을 올려 주니, 아직 안 켜 놨다면 설정해 두기를 권한다. ## 마무리 취약점은 누구의 잘못도 아니다. OSS 메인테이너도 사람이고, 공격 기법도 매일 진화한다. **중요한 건 "정기적으로 업데이트를 흡수해 가는 운영"을 프로젝트에 심는 것**. 이게 주니어와 프로 엔지니어를 가르는 분기점이기도 하다. `npm install multer@latest` 한 줄로, 새벽에 깨워질 확률이 확 줄어든다. 지금 바로 `package.json`을 열어 보자. --- **Refs (1차 정보):** - [GitHub Security Advisories — expressjs/multer](https://github.com/expressjs/multer/security/advisories) - [Multer 공식 리포지토리](https://github.com/expressjs/multer) - [npm package: multer](https://www.npmjs.com/package/multer)