← 기술 지식

기술 지식 / 보안 / 입력·웹 보안

서버 URL 조회의 목적지 검증과 연결 제한

URL 파싱·DNS·실제 연결·redirect를 하나의 허용 경계로 묶고 TLS 이름·egress·자격 전달·응답 예산을 설명합니다.

보안 · 원리·구현·운영
기술 지식 트리

서버가 외부 URL을 대신 읽는 기능은 문자열 검증만으로 안전해지지 않습니다. 허용할 이름을 정한 뒤 DNS 후보, 실제 연결 peer, redirect, TLS 이름, proxy, 응답 공개 범위를 같은 목적지 정책으로 묶어야 합니다. 각 단계의 재검사와 예산을 분리해 두면 SSRF 방어가 어디에서 끊겼는지 진단할 수 있습니다.

서버 측 URL 조회와 내부 목적지 접근 범위

사용자가 넣은 URL을 서버가 대신 읽어 미리보기를 만드는 기능을 떠올려 보겠습니다. 이때 서버가 가진 자격과 네트워크로 사용자가 직접 읽지 못하는 내부 관리 API나 클라우드 메타데이터 서비스까지 요청하면, 이를 SSRF(Server-Side Request Forgery, 서버 측 요청 위조)라고 부릅니다.

URL이 문법적으로 유효하고 scheme이 HTTPS여도 그 위치를 서버가 방문해도 된다는 뜻은 아닙니다. 목적지·해석·연결·응답 공개에 각각 제한이 필요합니다.

URL 허용 범위와 파서·연결 의미 일치

허용 범위는 가능하면 등록된 몇 도메인으로 먼저 좁힙니다. URL 파서가 분리한 scheme·hostname·port·userinfo(주소 안의 사용자 정보)를 검사해 사용하지 않는 항목을 거절합니다. 문자열에 도메인 이름이 들어 있는지나 접미사 일부만 맞는지로 허용 여부를 정하면 다른 host까지 허용할 수 있습니다. 국제 도메인·IP 리터럴·IPv6를 어떻게 정규화할지까지 같은 계약으로 맞춰야 파싱 결과와 연결 대상의 의미가 달라지지 않습니다.

경계 필요한 검사 남는 문제
URL 파싱 허용 scheme·host·port DNS의 실제 주소
이름 해석 허용 주소 범위·주소 후보 연결 때 재해석 변화
연결 검사한 대상과 실제 peer 결합 TLS 이름·proxy 경로
redirect 매 hop 새 목적지 검사 쿠키·Authorization 전달
응답 바이트·시간·형식 제한 사용자에게 공개할 권한

사설 주소 문자열 몇 개만 차단하는 목록은 모든 내부·특수 주소를 포괄한다고 단정할 수 없습니다. 환경에 맞는 네트워크 허용 정책과 검증된 주소 분류를 사용하고, IPv4-mapped IPv6 등 같은 목적지의 다른 표현도 다룹니다.

DNS 검사 주소와 실제 연결 주소의 결합

첫 DNS 조회에서 공개 주소를 받아 통과했더라도, HTTP 라이브러리가 연결할 때 다시 조회해 내부 주소를 고르면 첫 검사는 실제 peer를 보호하지 못합니다. 따라서 허용한 주소 후보를 실제 연결 대상과 결합하고, 재시도와 여러 A/AAAA 후보에도 같은 검사를 반복합니다. 특정 IP로 연결할 때도 TLS의 기대 hostname과 SNI는 원래 허용한 서비스 이름을 유지해야 그 이름에 맞는 인증서를 검증할 수 있습니다.

검사한 목적지와 실제 연결을 묶습니다URL 파싱·허용 목록. DNS 주소 후보 검사. 허용 주소에만 연결: 원래 TLS 이름 유지. 제한된 응답 읽기: redirect는 처음부터 재검사정규화한 host검사와 사용 결합시간·바이트 상한URL 파싱·허용 목록DNS 주소 후보 검사허용 주소에만 연결원래 TLS 이름 유지제한된 응답 읽기redirect는 처음부터 재검사
검사한 목적지와 실제 연결을 묶습니다 화살표는 한 hop의 처리 순서입니다. redirect가 발생하면 새 URL부터 같은 검사를 반복하고 총 횟수·시간 예산을 줄입니다.
그림을 글로 읽기
  • URL 파싱·허용 목록
  • DNS 주소 후보 검사
  • 허용 주소에만 연결: 원래 TLS 이름 유지
  • 제한된 응답 읽기: redirect는 처음부터 재검사
  1. URL 파싱·허용 목록 → DNS 주소 후보 검사: 정규화한 host
  2. DNS 주소 후보 검사 → 허용 주소에만 연결: 검사와 사용 결합
  3. 허용 주소에만 연결 → 제한된 응답 읽기: 시간·바이트 상한

프록시를 사용하면 실제 목적지의 이름 해석과 연결이 프록시에서 일어날 수 있습니다. 로컬 IP 확인만으로 프록시의 최종 peer를 증명하지 않습니다. 프록시 자체의 목적지 정책을 강제하거나 서버 조회 경로의 resolver·proxy 구성을 통제합니다. 환경 변수에서 우연히 상속된 proxy나 인증 설정도 조사합니다.

Redirect별 목적지·자격 재판단

허용된 공개 URL이 내부 주소로 redirect하는 상황을 막으려면 자동 따라가기를 끄거나, 따라갈 때마다 새 목적지를 검사할 수 있는 클라이언트를 사용합니다. 새 redirect 단계마다 URL 파싱·해석·연결을 다시 판단하고, 이동 횟수뿐 아니라 전체 deadline과 누적 응답 바이트도 제한합니다. 새 목적지에는 기존 쿠키·Authorization·클라이언트 인증서를 자동 전달하지 않습니다.

HTTP 오류나 느린 스트림·압축된 큰 응답도 예산 안에서 종료합니다. Content-Length가 없거나 거짓일 수 있으므로 실제 읽은 바이트와 해제 후 크기를 제한합니다. 응답을 앱 origin의 HTML로 다시 내보내면 XSS가 될 수 있어 텍스트 추출·안전한 미리보기·격리 origin 같은 별도 출력 정책을 둡니다.

네트워크 egress 경계와 독립 방어

조회 worker를 내부 관리자 권한과 클라우드 자격 없이 실행하고 egress에서 허용 목적지만 열어 둡니다. 앱 검사 오류가 생겨도 내부망 접근을 제한하는 독립 방어입니다. 기본 NetworkPolicy가 도메인·HTTP 경로별 정책을 모두 제공한다고 가정하지 않고 CNI·egress proxy의 실제 범위를 확인합니다.

읽을 수 있는 자료라고 모든 사용자에게 공개할 수 있는 것도 아닙니다. URL 접수자의 자격·목적·데이터 공개 범위를 별도로 검사합니다. 외부 서버의 응답 본문에 들어 있는 다음 URL이나 명령을 자동 실행하는 범위 확장도 피합니다.

통제된 테스트 resolver와 HTTP 서버에서 공개 주소, 금지 주소, redirect, 여러 A/AAAA 응답, 느린 스트림을 각각 재현하고 허용 목록·검사 주소·실제 peer·TLS hostname을 한 요청의 추적 ID로 대조하십시오. 예상 결과는 redirect 목적지가 새 정책을 통과하지 못하면 연결되지 않고, Content-Length가 없거나 압축된 응답도 실제 해제 후 바이트·시간 예산에서 종료되는 것입니다. 실제 내부 메타데이터나 타인의 서비스를 대상으로 검증하지 않습니다.

통제된 목적지와 허용·거절 동작 시험

자신이 관리하는 테스트 resolver·HTTP 서버로 공개 후보와 금지 후보, redirect, DNS 응답 변화, 다중 주소, 느린 응답을 재현합니다. 검사 로그의 허용 주소와 실제 연결 peer가 일치하는지 확인하고, 차단 결과만 아니라 정상 목적지의 TLS 이름 검증도 유지되는지 봅니다.

실제 내부 메타데이터나 타인의 서비스를 탐색하지 않습니다. 원문 URL의 자격·query 비밀을 로그에 남기지 않고 거절 단계·정규화한 목적지 분류·추적 ID로 진단합니다. 이 노트는 방어 설계이며 실제 서버에서 SSRF 시험을 실행한 보고서가 아닙니다.

후속·관련 개념

함께 읽을 문서

전체 기술 지식
선택 연습 · 관련 질문 1개

질문은 이해를 확인하는 보조 자료입니다. 학습 경로와 문서의 범위는 질문 수와 독립적입니다.