2024.02.19
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String "//"
개인적으로 운영하는 서비스가 두 개가 있는데, 두 군데 모두에서 저 에러가 자주 뜬다.
서비스에 영향도도 있다.
저 //를 열면 보안적으로 취약할 수 있다. 사용자의 요청 URL에 잠재적으로 악의적인 문자열 "//"가 포함되어 있을 수 있기 때문이다. 그러면 //는 어떤식으로 서버에 악영향을 끼칠 수 있는가. 조사 결과 대표적인 케이스가 세 가지가 있었다. 이외에도 다양하니 이 // 문자열 요청을 무턱대고 열어주는 것은 위험하다고 생각한다.
리소스 위치 혼동
웹 서버나 애플리케이션은 URL을 통해 요청된 리소스를 찾는다. 이중 슬래시(//)가 포함된 URL은 웹 서버에 따라 예상치 못한 방식으로 해석될 수 있으며, 이는 리소스를 찾지 못하거나 잘못된 리소스를 반환할 수 있다. 예를 들어, http://example.com//admin과 http://example.com/admin이 서로 다른 리소스로 해석될 수 있다.
보안 규칙 우회
웹 애플리케이션 방화벽(WAF)이나 다른 보안 메커니즘은 특정 URL 패턴을 차단하도록 구성될 수 있다. 공격자는 이중 슬래시를 사용하여 이러한 보안 규칙을 우회할 수 있다. 예를 들어, 보안 시스템이 /admin 경로에 대한 접근을 차단하는 경우, 공격자는 //admin을 사용하여 이 규칙을 우회할 수 있다.
디렉토리 트래버설 공격
공격자는 이중 슬래시를 사용하여 디렉토리 트래버설 공격을 시도할 수 있습니다. 이는 웹 애플리케이션의 보안 취약점을 이용하여 서버의 기대하지 않은 파일이나 디렉토리에 접근하는 것입니다. 예를 들어, URL에 포함된 이중 슬래시가 서버에서 무시되어 ../../etc/passwd와 같은 중요한 시스템 파일에 접근하는 데 사용될 수 있다.
서버 구성 오류
일부 웹 서버 구성에서는 이중 슬래시를 포함한 URL을 예상치 못한 방식으로 처리할 수 있으며, 이로 인해 서버 오류나 잘못된 콘텐츠 전달로 이어질 수 있다. 예를 들어, 서버가 내부적으로 URL을 재구성할 때 이중 슬래시를 잘못 처리하여 리소스를 찾지 못하는 경우가 있다.
이러한 위험이 있어서 나는 개발서버에 //를 열어놓고 프론트 개발자가 개발 시에 어떤 요청에서 저 에러가 발생하는지 잡으려고 했다.
먼저, 스프링 시큐리티에서 //를 열어주었다.
@Bean
public HttpFirewall allowUrlEncodedDoubleSlashHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedDoubleSlash(true);
return firewall;
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.httpFirewall(allowUrlEncodedDoubleSlashHttpFirewall());
}
그리고 아래와 같이 OncePerRequestFilter를 상속하여 모든 요청 중에서 //가 포함된 요청을 잡아 로그에 남기도록 했다.
@Component
public class DoubleSlashLoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String requestUri = request.getRequestURI();
if (requestUri.contains("//")) {
// 여기서 로그를 기록
logger.warn("Double slash detected in request URI: " + requestUri);
}
filterChain.doFilter(request, response);
}
}
이렇게 하고 기다리는 중이다.
아마도 예측컨데, 파일 업로드시에 발생하는 에러라고 추정된다.
이상한게 웹에서 내가 테스트할 때는 발생하지 않는데 모바일환경같은 곳에서 테스트하면 발생하는 듯 하다.