서버 사이드 요청 위조 (SSRF)
Server-Side Request Forgery (SSRF)
설명
서버 사이드 요청 위조(SSRF)는 서버가 외부로 보내는 HTTP 요청의 주소(URL)나 Host를 사용자 입력으로 그대로 사용해서 발생하는 취약점입니다. 공격자는 요청 파라미터나 헤더 등에 악의적인 URL을 넣어 서버에게 대신 요청을 보내게 만들 수 있습니다. 이 때 서버는 내부망(127.0.0.1, 메타데이터 엔드포인트, 사설 IP 등)이나 원래는 외부와 통신하면 안 되는 서비스로 요청을 보낼 수 있어, 인증 우회, 내부 시스템 정보 조회, 포트 스캐닝 등 다양한 공격이 가능합니다.
잠재적 영향
내부 네트워크 접근 (내부망 무단 접근): 서버가 있는 네트워크 내부(사설 IP, 내부 API, DB 관리 콘솔 등)에 사용자가 직접 접근할 수 있게 됩니다. 이를 통해 내부 시스템 구조 파악, 추가 공격(예: RCE로 이어지는 취약 API 호출) 등이 가능합니다.
민감 정보 유출 (내부 정보 노출): 클라우드 메타데이터 엔드포인트(예: AWS 169.254.169.254)나 내부 설정 서버에 요청을 보내 토큰, 크레덴셜, 설정 파일 등의 민감 정보를 획득할 수 있습니다.
서비스 악용 및 우회 (보안 정책 우회): 원래는 방화벽, IP 기반 ACL, WAF 등으로 막혀 있어야 하는 대상에게, 애플리케이션 서버를 프록시처럼 이용해 요청을 보낼 수 있어 보안 정책이 우회됩니다.
서비스 장애 유발 (서비스 거부): 의도적으로 느리거나 응답이 없는 주소, 매우 큰 응답을 보내는 서버로 요청을 반복해 보내 서버 자원을 소모시키고, 결과적으로 서비스 장애(DoS)를 일으킬 수 있습니다.
해결 방법
URL allowlist 사용: 외부 요청을 보낼 수 있는 도메인/호스트를 미리 정해둔 allowlist로 제한합니다. 예: "api.example.com" 또는 특정 IP/서브넷만 허용.
스킴/포트 검증: 입력 URL이 http/https만 사용하도록 제한하고, 80/443 등 허용 포트만 사용하게 합니다. file://, ftp://, gopher://, ssh://, mailto: 등은 차단합니다.
내부 IP/로컬호스트 차단: 127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 링크 로컬 주소, 0.0.0.0, localhost, ::1 등 내부/로컬 주소로의 요청을 금지합니다. DNS Rebinding을 막기 위해 DNS resolve 후 실제 IP 기반으로도 검증해야 합니다.
Base URL 고정: 사용자 입력을 전체 URL로 쓰지 말고, 서버에서 관리하는 고정 Base URL (예: https://api.example.com)을 사용하고, 사용자 입력은 path나 query parameter로만 사용합니다.
HTTP Client 레벨 제한: 요청 타임아웃 설정, 리다이렉트 횟수 제한, 응답 크기 제한 등을 설정하여 DoS 성 SSRF를 완화합니다.
입력 포맷 검증 및 인코딩: path, query에 들어가는 값은 URL 인코딩하고, 허용 문자(알파벳, 숫자, -, _, . 등)만 허용하는 화이트리스트 검증을 적용합니다.
보안 테스트 및 모니터링: SSRF 취약점에 특화된 테스트 케이스를 작성하고, 의심스러운 아웃바운드 요청 로그를 모니터링합니다.
취약한 코드 및 안전한 코드 예시
취약한 코드
안전한 코드
설명:
취약한 코드: 비준수 코드에서는 사용자가 query parameter "url"로 보낸 값을 아무 검증 없이 http.Get에 그대로 전달합니다. 이 경우 공격자는 내부망이나 클라우드 메타데이터 엔드포인트 같은 민감한 주소를 넣어 서버에게 대신 요청을 보내게 만들 수 있습니다. 서버는 네트워크 상에서 더 신뢰받는 위치에 있기 때문에, 원래는 외부에서 직접 접근할 수 없는 시스템에 접근이 가능해지고, 그 응답 내용을 공격자에게 그대로 전달할 수 있어 SSRF 취약점이 발생합니다.
안전한 코드: 준수 코드에서는 다음과 같이 SSRF 위험을 줄입니다.
사용자 입력을 전체 URL이 아니라 path 형태로만 받습니다.
Base URL("https://api.example.com")을 서버에서 고정해, 임의의 호스트로 요청하지 못하게 합니다.
allowedHosts 맵을 통해 허용된 도메인만 요청할 수 있도록 제한합니다.
DNS Lookup을 수행해 실제 IP를 얻은 후, 사설 IP 대역이나 localhost로 향하는 요청은 차단합니다.
http.Client에 타임아웃을 설정하여 느린 응답으로 인한 자원 고갈을 방지합니다. 이러한 방어 로직을 통해 사용자 입력이 HTTP client의 대상 호스트/URL을 직접 지배하지 못하게 만들고, SSRF 취약점이 발생할 가능성을 크게 낮춥니다.
참조
Last updated