malicious String "//" - RequestRejectedException 처리기

연어는결국강으로·2024년 2월 19일

2024.02.19

1. 뭐임?

org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String "//"

개인적으로 운영하는 서비스가 두 개가 있는데, 두 군데 모두에서 저 에러가 자주 뜬다.
서비스에 영향도도 있다.

저 //를 열면 보안적으로 취약할 수 있다. 사용자의 요청 URL에 잠재적으로 악의적인 문자열 "//"가 포함되어 있을 수 있기 때문이다. 그러면 //는 어떤식으로 서버에 악영향을 끼칠 수 있는가. 조사 결과 대표적인 케이스가 세 가지가 있었다. 이외에도 다양하니 이 // 문자열 요청을 무턱대고 열어주는 것은 위험하다고 생각한다.

  1. 리소스 위치 혼동
    웹 서버나 애플리케이션은 URL을 통해 요청된 리소스를 찾는다. 이중 슬래시(//)가 포함된 URL은 웹 서버에 따라 예상치 못한 방식으로 해석될 수 있으며, 이는 리소스를 찾지 못하거나 잘못된 리소스를 반환할 수 있다. 예를 들어, http://example.com//admin과 http://example.com/admin이 서로 다른 리소스로 해석될 수 있다.

  2. 보안 규칙 우회
    웹 애플리케이션 방화벽(WAF)이나 다른 보안 메커니즘은 특정 URL 패턴을 차단하도록 구성될 수 있다. 공격자는 이중 슬래시를 사용하여 이러한 보안 규칙을 우회할 수 있다. 예를 들어, 보안 시스템이 /admin 경로에 대한 접근을 차단하는 경우, 공격자는 //admin을 사용하여 이 규칙을 우회할 수 있다.

  3. 디렉토리 트래버설 공격
    공격자는 이중 슬래시를 사용하여 디렉토리 트래버설 공격을 시도할 수 있습니다. 이는 웹 애플리케이션의 보안 취약점을 이용하여 서버의 기대하지 않은 파일이나 디렉토리에 접근하는 것입니다. 예를 들어, URL에 포함된 이중 슬래시가 서버에서 무시되어 ../../etc/passwd와 같은 중요한 시스템 파일에 접근하는 데 사용될 수 있다.

  4. 서버 구성 오류
    일부 웹 서버 구성에서는 이중 슬래시를 포함한 URL을 예상치 못한 방식으로 처리할 수 있으며, 이로 인해 서버 오류나 잘못된 콘텐츠 전달로 이어질 수 있다. 예를 들어, 서버가 내부적으로 URL을 재구성할 때 이중 슬래시를 잘못 처리하여 리소스를 찾지 못하는 경우가 있다.


2. 그래서?

이러한 위험이 있어서 나는 개발서버에 //를 열어놓고 프론트 개발자가 개발 시에 어떤 요청에서 저 에러가 발생하는지 잡으려고 했다.

먼저, 스프링 시큐리티에서 //를 열어주었다.

    @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);
    }
}

이렇게 하고 기다리는 중이다.

아마도 예측컨데, 파일 업로드시에 발생하는 에러라고 추정된다.
이상한게 웹에서 내가 테스트할 때는 발생하지 않는데 모바일환경같은 곳에서 테스트하면 발생하는 듯 하다.

profile
내 블로그를 보는 시간에 LLM에게 질문을 한번 더 하는게 현명할지도....?

0개의 댓글