1. X-Forwarded-For 헤더란?
X-Forwarded-For(이하 XFF) 헤더는 HTTP 프록시나 로드밸런서 앞단에서 클라이언트의 실제 IP를
백엔드 서버로 전달하기 위한 비표준 헤더다.

위와 같이 Client가 Firewall과 Load Balancer를 거처서 들어가는 통신을 한다고 가정했을 때
Web server는 Load Balancer 의 IP만 확인가능하기 때문에 실제 client IP를 식별하지 못한다.
따라서 Load Balancer 가 실제 client의 IP를 X-Forwarded-For header에 담아 Backend로 전달하는 방식
(위의 그림에서는 실제 Client IP가 아닌 Gateway IP가 들어감.)
그러면 왜 XFF header를 통해 client의 실제 IP를 식별하는걸까?
이유 1. 보안 정책 + 접근 제어
- 내부 관리자 페이지일 경우 특정 IP에서만 접근 가능하도록 제한하고자 할 수 있음
- API 호출과 관련해서 허용된 IP 대역만 허용하고자 할 때 사용
이유 2. 로깅 및 추적 + 이상 행위 탐지
- 특정 IP가 너무 많은 요청을 전송 시 이를 차단해야 함
- 서비스 운영에 있어서 누가, 언제, 어디서 접속했는지를 남겨야 함
2. X-Forwarded-For 헤더 구조
XFF 헤더에는 보통 다음과 같은 형식으로 값이 들어간다.
X-Forwarded-For: [Client-IP], [Proxy1-IP], [Proxy2-IP] ...
ex). X-Forwarded-For: 203.0.113.50, 100.100.100.10
- 가장 앞의 IP = 실제 클라이언트 IP (Gateway IP)
- 이후의 IP = 거친 프록시 IP

3. 인가 우회 취약점은 왜 발생하나?
많은 백엔드 서버는 사용자의 실제 IP를 확인할 때 다음과 같은 코드를 사용한다.
client_ip = request.headers.get("X-Forwarded-For", request.remote_addr)
🧨 문제는?
X-Forwarded-For 값은 클라이언트가 직접 조작할 수 있다!
즉, 이런 경우
GET /api/user-info HTTP/1.1
Host: target.com
X-Forwarded-For: 202.1.115.70 ← 내가 조작한 IP (ex. 관리자 권한이 있는 IP 부여)
진짜 IP라고 착각해서, ACL(Access Control List)이나 IP 기반 인가 로직에서 잘못된 판단을 할 수 있다.

위와 같은 방식으로 XFF 취약점을 활용한 공격을 진행하게 되면
인가 취약점이 발생하게 됨
(ex1. admin 권한 없는 일반 user가 admin 권한의 page 접근 가능)
(ex2. 일반 권한을 가진 user가 admin 권한만 요청 가능한 api 요청 가능)
4. 대응 방안 예시
📌 Nginx + Spring 예시 (LB 또는 리버스 프록시에서)
real_ip_header X-Forwarded-For;
set_real_ip_from 203.0.113.1/24; # 신뢰할 수 있는 프록시 IP 대역
// Spring Boot에서 클라이언트 IP 가져오기
String ip = request.getHeader("X-Forwarded-For");
if (ip == null) {
ip = request.getRemoteAddr();
}
LoadBalancer는 트래픽 부하 분산을 위한 목적으로 구동되기 때문에
보안적인 부분을 판단하지 않는다!
따라서 server에서 XFF에 대한 값을 무조건 신뢰하면 안되고 이에 대한 검증 로직을 추가하거나
신뢰할 수 있는 proxy IP 대역만을 허용할 수 있도록 설정하는 것이 좋다.
'웹 보안' 카테고리의 다른 글
| 워드프레스 API 취약점 (0) | 2025.11.29 |
|---|---|
| Non HTTP Proxy (0) | 2025.02.14 |
| Hidden XSS (0) | 2025.01.16 |
| Cookie, Session, Token (0) | 2025.01.01 |
| Smart_Editor 2.0 File Upload Exploit (0) | 2024.06.26 |
