1. HttpFirewall
- Spring Security의 FilterChainProxy가 들어오는 HTTP 요청을 검사하고, 보안상 위험한 요청을 차단하는 방화벽
- ✅ 서블릿 컨테이너마다 세미콜론, 중복 슬래시, 인코딩 문자 등 해석하는 방식이 다름
- ⚠️ 이 차이를 이용하면 보안 필터가 검사한 경로와 실제 애플리케이션이 처리한 경로가 달라 규칙을 우회할 수 있음
역할
| 구분 | 설명 | 검사 대상 |
| 요청 검증 | 악의적이거나 모호한 요청을 식별하고 거부 | URL, HTTP 메서드, 헤더, 파라미터, Host |
| 경로 일관성 확보 | 보안 경로 매칭에 사용할 일관된 요청 경로 제공 | servletPath, pathInfo |
| 응답 보호 | 응답 헤더에 개행 문자가 삽입되는 것을 차단 | \r, \n이 포함된 응답 헤더 |
| 필터 체인 우회 방지 | 컨테이너별 URL 해석 차이를 이용한 인가 우회 방지 | 세미콜론, 중복 슬래시, 인코딩 문자 등 |
StrictHttpFirewall
- SpringSecurity Servlet 환경에서 자동으로 적용되는 HttpFirewall 기본 구현체
- ✅ 의심스러운 요청을 정규화하여 허용하기보다 RequestRejectedException을 발생시켜 요청을 거부함
| 차단 요소 | 예시 | 차단 이유 |
| 정규화되지 않은 URL | /a/../admin, /api//admin | 경로 해석 차이를 이용한 인가 우회 방지 |
| 세미콜론 포함 경로 | /secure;jsessionid=abc | 경로 파라미터나 세션 ID를 이용한 우회 방지 |
| 위험한 인코딩 문자 | %2F, %00, \ | 디코딩 차이와 경로 우회 방지 |
| 허용되지 않은 HTTP 메서드 | TRACE, CONNECT | XST, HTTP Method 우회 공격 방지 |
| 비정상 헤더·파라미터 | \r, \n, 제어 문자 포함 | Header Injection, 파싱 오류 방지 |
| 비정상 Host | Host: evil.example | Host Header Injection 방지 |
2. 커스터마이징
설정) 세미콜론 허용
더보기
@Bean
public StrictHttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
return firewall;
}
- URL에 세미콜론을 허용할 수 있습니다.
설정) HTTP 메소드 허용 목록
더보기
@Bean
public StrictHttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowedHttpMethods(Arrays.asList("GET", "POST"));
return firewall;
}
- 공격을 방지하기 위해 허용되는 HTTP 메소드 목록 설정 가능 (XST, HTTP Verb Tampering 등)
- setAllowedHttpMethods 사용하여 허용되는 HTTP 메소드를 GET 및 POST로만 설정할 수 있습니다.
- 기본적으로 모든 메소드가 허용됨
설정) 헤더 및 파라미터 이름 및 값 검증
더보기
@Bean
public StrictHttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowedHeaderNames((header) -> true);
firewall.setAllowedHeaderValues((header) -> true);
firewall.setAllowedParameterNames((parameter) -> true);
return firewall;
}
설정) 특정 값 허용
더보기
@Bean
public StrictHttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
Pattern allowed = Pattern.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]]*");
Pattern userAgent = ...;
firewall.setAllowedHeaderValues((header) -> allowed.matcher(header).matches() || userAgent.matcher(header).matches());
return firewall;
}
예를 들어 iPhone Xʀ는 ISO-8859-1 문자 집합에 포함되지 않는 문자를 포함하는 User-Agent를 사용합니다.
- 이로 인해 일부 애플리케이션 서버는 이 값을 두 개의 별도 문자로 구문 분석합니다.
- 이를 처리하기 위해 setAllowedHeaderValues 메소드를 사용하여 특정 User-Agent를 허용할 수 있습니다.
설정) 헤더 값을 UTF-8로 구문 분석
더보기
firewall.setAllowedHeaderValues((header) -> {
String parsed = new String(header.getBytes(ISO_8859_1), UTF_8);
return allowed.matcher(parsed).matches();
});
- 헤더 값의 경우, 검증 시점에 이를 UTF-8로 구문 분석하는 것을 고려할 수 있습니다.
출처
'Spring > Spring Security' 카테고리의 다른 글
| [Spring Security] 4-2. Authorization: HttpServletRequests (2) | 2025.07.11 |
|---|---|
| [Spring Security] 4-1. Authorization: Architecture (0) | 2025.07.03 |
| [Spring Security] 5-3. 보안: HTTP Requests (0) | 2023.10.14 |
| [Spring Security] 5-2. 보안: Security HTTP Response Headers (3) | 2023.10.14 |
| [Spring Security] 5-1. 보안: CSRF (0) | 2023.10.06 |