FlawOpen

flawopen.com/SSRF/Node.js fetch()와 SSRF

Node.js fetch()는 SSRF를 막아 주나요?

CWE-918: Server-Side Request ForgeryNode.js 보안 참고 자료
쉽게 설명하면

아니요. 서버의 fetch()는 서버에서 요청을 보냅니다. 호출자가 목적지를 정하면 자신은 접근할 수 없는 시스템에 서버를 보내도록 유도할 수 있습니다. 주소를 확인하지 않고 택배를 보내는 것과 같습니다. 위험은 서버 네트워크, 권한, URL 정책과 리디렉션에 달려 있습니다.

SSRF (CWE-918)신뢰할 수 없는 호출자가 선택하거나 영향을 준 목적지로 서버가 요청해 네트워크 신뢰 경계를 넘는 문제입니다.
목적지 허용 목록providerId 같은 사용자 선택을 앱에서 설정한 출처에 고정 매핑해 임의 URL을 받지 않습니다.
리디렉션 검증응답이 두 번째 목적지를 지정할 수 있습니다. 자동으로 따라가면 최초 URL만 검사한 정책을 우회할 수 있습니다.
DNS rebinding호스트명이 다른 IP로 해석될 수 있습니다. DNS를 한 번 검사한 뒤 HTTP client가 다시 해석하면 TOCTOU 틈이 생깁니다.

근본 원인: 서버가 호출자 선택 목적지를 신뢰

Node.js fetch()는 일반 HTTP client이지 SSRF 정책 엔진이 아닙니다. 허용 네트워크를 결정하지 않으며 브라우저 CORS도 서버 경계를 만들지 않습니다. URL 파싱만으로는 부족합니다. 허용 hostname이 금지 IP로 해석되거나 응답이 다른 host로 redirect할 수 있습니다. 사용자 avatar, webhook, 문서, 미리보기를 가져오는 기능이 위험 경로가 됩니다.

요청이 신뢰 경계를 넘는 과정

Step 1

호출자가 URL에 영향을 줌

이미지 미리보기처럼 endpoint가 전체 URL이나 URL을 구성할 데이터를 받습니다.

Step 2

서버가 요청을 보냄

HTTP client는 서버 프로세스의 네트워크 경로, DNS, proxy와 권한을 사용합니다.

Step 3

리디렉션이 목적지를 바꿈

Fetch는 기본적으로 redirect를 따릅니다. 처음 허용된 대상이 Location으로 금지된 host를 가리킬 수 있습니다.

Step 4

응답이 접근 가능한 데이터를 노출

네트워크와 정책에 따라 내부 서비스나 클라우드 metadata에 닿을 수 있습니다. 모든 fetch에서 자동 발생하는 것은 아닙니다.

위험한 Node.js 패턴과 안전한 패턴

위험
// 호출자가 준 임의 URL을 가져오지 마세요.
const response = await fetch(userProvidedUrl);
더 안전
// 호출자는 key만 고르고 네트워크 목적지는 고르지 않습니다.
const destinations = new Map([
  ["status", new URL("https://status.example/")],
  ["docs", new URL("https://docs.example/")],
]);

const target = destinations.get(providerId);
if (!target) throw new Error("Unknown provider");

const response = await fetch(target, {
  redirect: "error",
  signal: AbortSignal.timeout(3000),
});
if (!response.ok) throw new Error("Upstream request failed");

사용자가 URL을 입력해야 한다면

가능하면 provider ID만 받고 고정 목적지 맵으로 요청을 만드세요. 임의 공개 URL이 필수라면 필요한 scheme과 port만 허용하고 user-info, loopback, private, link-local 및 금지된 IPv4/IPv6 주소는 거부합니다. 모든 DNS 주소를 검증하고 재검증되지 않은 lookup 없이 검증된 IP로 연결합니다. 자동 redirect를 끄거나 매 홉을 검증하세요. 169.254.169.254와 활성화된 IPv6 metadata를 포함해 outbound 네트워크도 제한합니다. 시간, 응답 크기, 동시성을 제한하고 내부 자격 증명은 전달하지 않습니다.

SSRF 방지 체크리스트

자주 묻는 질문

localhost와 private IP를 막으면 충분한가요?

아니요. redirect, IPv4/IPv6 표기, DNS rebinding, proxy, DNS 확인과 연결 사이의 경합이 단순 검사를 우회할 수 있습니다. 고정 허용 목록을 우선하고 임의 목적지가 필요하면 모든 주소를 검증해 연결을 고정하며 네트워크 출구에서도 차단하세요.

IMDSv2가 SSRF를 없애나요?

아니요. IMDSv2 토큰 절차는 일부 위험을 줄이지만 다른 내부 서비스나 설정에 따른 metadata는 여전히 대상이 될 수 있습니다. 목적지와 egress 제어를 유지하세요.

1차 출처

관련 보안 주제와 사고 분석 살펴보기:전체 보안 디렉터리 →
함께 보기 서버 측 요청 위조(SSRF, CWE-918): 동작 원리와 언어별 방어 방법 — flawopen.com SSRF와 클라우드 메타데이터: 자격 증명 위험과 방어 AI PR 봇 SSRF 방어 — flawopen.com