반응형
X-Forwarded-For 취약점 방지
XFF ( X-Forwarded-For )란?
클라이언트 IP ⟶ Proxy 서버 및 장비 ⟶ 웹 서버
X-Forwarded-For는 일반적으로 HTTP 헤더의 일부로 클라이언트의 IP 주소를 식별하는 데 사용. 이 헤더는 웹 요청이 프록시(Proxy) 또는 로드 밸런서(Road Balancer)를 통해 이루어질 때 실제 요청을 보낸 클라이언트의 IP를 식별할 때 유용하게 사용.
일반적인 형식 - X-Forwarded-For: client, proxy1, proxy2
XFF 취약점 보완
// 검증 코드
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
public class XFFValidation {
// 신뢰할 수 있는 프록시 IP 목록
private static final List<String> TRUSTED_PROXIES = Arrays.asList("192.168.0.1", "10.0.0.1");
public static String getClientIpAddress(HttpServletRequest request) {
String remoteAddr = "";
// 신뢰할 수 있는 프록시에서의 요청만 처리
String ipFromHeader = request.getHeader("X-Forwarded-For");
if (ipFromHeader != null && !ipFromHeader.isEmpty()) {
// XFF 헤더를 파싱하여 첫 번째 IP 주소 추출
remoteAddr = ipFromHeader.split(",")[0];
}
// 요청이 신뢰할 수 있는 프록시를 통해 왔는지 확인
if (TRUSTED_PROXIES.contains(request.getRemoteAddr())) {
// 신뢰할 수 있는 프록시에서 온 요청일 경우, XFF 헤더에서 추출한 IP 반환
return remoteAddr;
} else {
// 신뢰할 수 없는 프록시에서 온 요청일 경우, 직접 연결된 클라이언트의 IP 반환
return request.getRemoteAddr();
}
}
}
// 인터셉터
//import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; // 없어지는 추세
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//public class XFFInterceptor extends HandlerInterceptorAdapter { // 없어지는 추세
public class XFFInterceptor implements HandlerInterceptor {
@Override
// preHandle : 요청 처리 전 클라이언트 IP 검증
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// XFFValidation 클래스에서 getClientIpAddress 메소드 사용( 클라이언트 IP 주소 추출 )
String clientIp = XFFValidation.getClientIpAddress(request);
System.out.println("Client IP: " + clientIp);
// 추가적인 검증 로직 구현 가능
// 요청을 계속 진행시키려면 true를 반환
return true;
}
// 필요에 따라 postHandle 및 afterCompletion 메소드 구현
}
// WebMvcConfigurer에 추가
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new XFFInterceptor());
}
}
Interceptor / Filter
Interceptor | Filter | |
공통점 | 특정 URI에 접근 할 때 제어 하는 용도로 사용 | |
차이점 | - DispatcherServlet과 동작 - 용도 1. 인증/인가 등과 같은 공통작업 2. Controller로 넘겨주는 정보의 가공 3. API 호출에 대한 로깅 또는 감사 |
- DispatcherServlet 처리 전•후 동작 - JAVA Servlet에서 제공 - 용도 1. 보안 관련 공통 작업 2. 모든 요청에 대한 로깅 또는 감사 3. 이미지/데이터 압축 및 문자열 인코딩 |
특징 | - 메서드 | - Filter Chain : 여러 필터가 연쇄적으로 동작 - 메서드 |
HandlerInterceptor인터페이스
public interface HandlerInterceptor {
// return이 true면 다음 동작 실행 / false면 중단
// Contoller 동작 이전
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
// Contoller 동작 이후
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
// 화면 처리(뷰)가 완료된 상태
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
Filter인터페이스
public interface Filter {
//init : 필터가 웹 컨테이너에 생성될 때 실행
public default void init(FilterConfig filterConfig) throws ServletException {}
//doFilter : Request, Response가 필터를 거칠 때 수행되는 메소드로, 체인을 따라 다음에 존재하는 필터로 이동합니다.
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
//destroy : 필터가 소멸될 때 실행
public default void destroy() {}
}
반응형
'Backend > JAVA' 카테고리의 다른 글
Response로 Json 생성 (0) | 2024.02.19 |
---|---|
Gradle-JDK이슈 (0) | 2024.02.16 |
12/19 회고 (0) | 2023.12.19 |
12/15 뻘짓 (0) | 2023.12.15 |
12/06 회고 (0) | 2023.12.06 |