목록으로 돌아가기
Security
4분 읽기

Axios CVE-2026-40175 분석 — 프로토타입 오염 가젯과 AWS 탈취

Axios의 단순한 설정 병합 로직이 어떻게 AWS 계정 탈취까지 이어지는 치명적인 가젯이 되는지 분석한다.

ㅂㄹㄱ

2026-04-15

이 글은 Node.js 생태계에서 가장 널리 쓰이는 HTTP 클라이언트인 Axios의 치명적인 취약점을 다룬다.
단순한 라이브러리 업데이트 이상의 보안적 함의를 분석한다.

들어가며

최근 Axios에서 CVSS 점수 9.9(Critical)라는 경이로운 수치의 취약점이 보고됐다. 처음에는 "HTTP 클라이언트에서 어떻게 이런 점수가 나오지?" 싶었지만, 내용을 뜯어보니 단순한 버그가 아니었다. 이 취약점은 단독으로 동작하기보다 다른 취약점과 결합하여 시스템을 완전히 장악하는 가젯(Gadget) 역할을 한다. 특히 AWS 같은 클라우드 환경에서는 인스턴스 권한을 통째로 넘겨줄 수 있는 수준이다.


취약점의 핵심: 가젯(Gadget)과 체이닝

CVE-2026-40175를 이해하려면 먼저 '가젯'이라는 개념을 알아야 한다. 이 취약점은 Axios 자체가 직접 데이터를 오염시키는 것이 아니다. 다른 곳에서 발생한 오염을 이용해 치명적인 동작을 완성하는 부품 역할을 한다.

공격의 흐름은 다음과 같은 단계로 진행된다.

graph TD
    A[공격자 데이터 주입] --> B[Polluter: qs, lodash 등의 취약점 이용]
    B --> C[Object.prototype 오염]
    C --> D[Gadget: Axios 설정 병합 시 오염된 속성 상속]
    D --> E[HTTP Header Injection / CRLF 주입]
    E --> F[Request Smuggling 발생]
    F --> G[AWS IMDSv2 우회 및 자격 증명 탈취]
Diagram: graph TD A[공격자 데이터 주입] --> B[Polluter: qs, lodash 등의 취약점 이용] B --> C[Object.prototype 오염] C --> D[Gadget: Axios 설정 병합 시 오염된 속성 상속] D --> E[HTTP Header Injection / CRLF 주입] E --> F[Request Smuggling 발생] F --> G[AWS IMDSv2 우회 및 자격 증명 탈취]

1. 프로토타입 오염 방어 실패

Axios는 내부적으로 요청 설정을 합치는 Deep Merge 과정을 거친다. 이때 객체의 속성이 자신의 것인지 프로토타입에서 온 것인지 검증하지 않았다. 공격자가 환경을 미리 오염시켜 두었다면, Axios는 오염된 값을 정당한 HTTP 헤더로 인식하고 서버로 전송한다.

2. CRLF 검증 미비

더 심각한 점은 헤더 값에 포함된 개행 문자(\r\n, CRLF)를 걸러내지 않았다는 것이다. HTTP 프로토콜에서 CRLF는 요청의 끝이나 구분을 의미한다. 이를 이용해 하나의 HTTP 연결 안에 또 다른 가짜 요청을 끼워 넣는 Request Smuggling이 가능해진다.


왜 클라우드 환경에서 더 치명적인가

이 취약점이 9.9점이라는 높은 점수를 받은 이유는 클라우드 보안 모델을 무력화하기 때문이다. 대표적인 타겟은 AWS의 IMDSv2(Instance Metadata Service v2)다.

기존의 단순한 SSRF 공격은 GET 요청만 가능했다. 하지만 IMDSv2는 보안을 위해 반드시 PUT 메서드와 특정 헤더를 요구한다. Axios의 이번 취약점을 이용하면 다음과 같은 시나리오가 성립한다.

  1. 공격자가 프로토타입에 PUT 요청이 포함된 페이로드를 심는다.
  2. Axios가 외부로 요청을 보낼 때, 헤더 사이에 숨겨진 PUT 요청이 함께 나간다.
  3. 서버 내부의 프록시나 메타데이터 서비스는 이를 별도의 정당한 요청으로 오해한다.
  4. 공격자는 인스턴스의 IAM 권한(Access Key 등)을 획득하고 클라우드 계정을 탈취한다.

그런데 정말 그렇게 위험한가

시나리오만 보면 당장 서버가 털릴 것 같지만, 한 가지 중요한 사실을 짚고 넘어가야 한다. 표준 Node.js 환경에서는 이 공격이 현실적으로 작동하지 않는다.

Node.js, Bun, Deno 같은 주요 런타임은 이미 수년 전부터 HTTP 헤더에 포함된 CRLF 문자를 런타임 레벨에서 거부해 왔다. Axios가 오염된 헤더 값을 그대로 내보내려 해도, 그 아래 HTTP 모듈이 요청을 쏘기 직전에 차단한다. CRLF 필터가 Axios 바깥에 한 겹 더 있는 셈이다.

실제로 이 취약점을 악용하려면 다음 조건이 모두 맞아야 한다.

  1. 스택 어딘가에서 이미 프로토타입 오염이 일어나고 있다.
  2. Axios가 커스텀 어댑터를 사용해 Node 내장 HTTP 클라이언트를 우회한다.
  3. 혹은 소켓을 직접 조작하는 비표준 구현을 쓴다.
  4. 내부망에 도달 가능한 메타데이터 엔드포인트가 열려 있다.

결국 "9.9짜리 폭탄이 실전에서 터지려면 설치 방식을 비표준으로 틀어놓아야 한다"는 이야기다. 그렇다고 방심할 수는 없다. 의존성은 언제 갈아끼워질지 모르고, 커스텀 어댑터를 쓰는 환경(테스트 mock, React Native, Electron 등)도 적지 않다. 내 환경이 안전하다고 가정하는 대신, 그냥 패치하는 쪽이 훨씬 싸게 먹힌다.


대응 방법

이 취약점은 패치가 이미 나와 있다. 단순히 버전을 올리는 것만으로도 가젯으로서의 연결 고리를 끊을 수 있다.

npm install axios@latest
yarn add axios@latest
pnpm add axios@latest

권장 버전

  • 1.15.0 이상 (최신 메인라인)
  • 0.31.0 이상 (0.x 계열 사용자용)

공식 advisory를 보면 Affected: <1.13.2, Patched: >=1.15.0 으로 표기되어 있어 1.13.2 ~ 1.14.x 구간이 붕 떠 있다. 이는 1.13.2에서 1차 완화가 들어간 뒤 변종 우회가 발견되어 1.15.0에서 설정 병합 로직을 근본적으로 수정했기 때문이다. 가급적 최신 버전으로 업데이트하는 것을 권장한다.


정리

CVE-2026-40175는 현대적인 웹 개발에서 의존성 관리가 얼마나 중요한지 다시 한번 일깨워준다. 내 코드가 안전하더라도, 내가 믿고 쓰는 라이브러리가 공격자의 도구로 변할 수 있다.

구분내용
위험 등급Critical (CVSS 9.9)
핵심 원인프로토타입 상속 무검증 + CRLF 미검증
주요 위협HTTP Request Smuggling, AWS 계정 탈취
해결책Axios 1.15.0 또는 0.31.0 이상으로 업데이트

단순히 업데이트를 실행하는 것에 그치지 말고, npm audit을 통해 내 프로젝트의 어떤 패키지가 오염원(Polluter)이 될 수 있는지 주기적으로 점검해야 한다. 보안은 가장 약한 연결 고리만큼만 강하기 때문이다.


참고자료

자주 묻는 질문

1.13.2나 1.14.x를 쓰고 있으면 안전한가?
공식 advisory는 affected 범위를 `<1.13.2`로 표기하지만, patched 버전은 `>=1.15.0`부터다. 1.13.2에서 1차 완화가 들어간 뒤 변종 우회가 발견되어 1.15.0에서 설정 병합 로직이 근본적으로 수정됐다. 1.13.2 ~ 1.14.x는 공식적으로 patched로 인정되지 않은 구간이므로, 1.15.0 이상으로 올리는 것이 안전하다.
브라우저 환경에서 axios를 쓸 때도 영향받나?
이 취약점의 핵심 시나리오는 서버사이드 HTTP Request Smuggling과 AWS IMDSv2 같은 내부 메타데이터 엔드포인트 탈취다. 브라우저에서는 XHR/fetch 레이어가 CRLF 헤더를 차단하고, 내부망 메타데이터 서비스에도 도달할 수 없어 실질적인 영향은 거의 없다. 그래도 의존성 버전은 최신으로 유지하는 편이 좋다.
내 프로젝트가 취약한지 어떻게 확인하나?
`npm ls axios`로 직/간접 의존 버전을 확인하고 `npm audit`으로 권고문 매칭 여부를 점검한다. pnpm과 yarn은 각각 `pnpm why axios`, `yarn why axios`로 확인할 수 있다. 전이 의존성으로 낡은 버전이 박혀 있는 경우가 흔하니 `overrides`(npm/pnpm) 또는 `resolutions`(yarn)로 강제 업그레이드를 걸어야 할 수도 있다.
CVSS 9.9인데 왜 실전 악용이 어렵다고 하는가?
CVSS 점수는 이론적 최악 시나리오를 기준으로 매겨진다. 실제 Node.js, Bun, Deno 런타임은 HTTP 헤더에 CRLF가 포함된 요청 자체를 수년 전부터 차단해 왔기 때문에, 표준 구성에서는 페이로드가 소켓 밖으로 나가지 못한다. 커스텀 어댑터로 내장 HTTP 모듈을 우회하거나 소켓을 직접 조작하는 비표준 구현에서만 악용이 성립한다.