Spring Security - Rejected Request

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

μš”μ²­μ΄ κ±°λΆ€λ˜λŠ” 이유

일반적으둜 μŠ€ν”„λ§ λΆ€νŠΈ 기반의 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μŠ€ν”„λ§ μ‹œνλ¦¬ν‹°λ₯Ό μ‚¬μš©ν–ˆλ‹€λ©΄ 기본적으둜 μ μš©λ˜λŠ” HttpFirewall κ΅¬ν˜„μ²΄μ— μ˜ν•΄ μ—°μ†λ˜λŠ” μŠ¬λž˜μ‹œ 문자λ₯Ό ν—ˆμš©ν•˜μ§€ μ•Šλ„λ‘ λ˜μ–΄μžˆλ‹€. REST API둜 λ””μžμΈν•˜λŠ” 경우 PathVariable 둜 경둜 μƒμ˜ λ¦¬μ†ŒμŠ€ 아이디λ₯Ό κ²€μ¦ν•˜λŠ” κ²½μš°κ°€ λŒ€λΆ€λΆ„μ΄λ‹€. λ”°λΌμ„œ, λŒ€λΆ€λΆ„μ˜ 경우 URL 경둜 상 μ—°μ†λœ μŠ¬λž˜μ‹œ λ¬ΈμžλŠ” μ„œλ²„ μž…μž₯μ—μ„œ 잘λͺ»λœ μš”μ²­μ— ν•΄λ‹Ήλœλ‹€.

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
    return webSecurity -> webSecurity.httpFirewall(httpFirewall())
            .ignoring().requestMatchers("/error");
}

@Bean
public HttpFirewall httpFirewall() {
    // NOTE: Spring Security provides DefaultHttpFirewall and StrictHttpFirewall.
    StrictHttpFirewall httpFirewall = new StrictHttpFirewall();
    httpFirewall.setAllowSemicolon(false);
    httpFirewall.setAllowNull(false);
    httpFirewall.setAllowBackSlash(false);
    httpFirewall.setAllowUrlEncodedDoubleSlash(false);

    List<String> allowedHttpMethods = Stream.of(
                    HttpMethod.GET,
                    HttpMethod.POST,
                    HttpMethod.PUT,
                    HttpMethod.DELETE,
                    HttpMethod.OPTIONS)
            .map(HttpMethod::name)
            .toList();
    httpFirewall.setAllowedHttpMethods(allowedHttpMethods);
    return httpFirewall;
}

κ±°λΆ€λœ μš”μ²­μ„ λ¬΄μ‹œν•˜μ§€ 말고 μΆ”μ ν•˜μ„Έμš”

μ˜¬λ°”λ₯Έ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ•„λ‹Œ 봇에 μ˜ν•œ 잘λͺ»λœ μš”μ²­μΌ 수 μžˆμœΌλ‚˜ ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμžκ°€ μ„œλ²„μ—μ„œ μš”κ΅¬ν•˜λŠ” REST API μ„€κ³„λŒ€λ‘œ μš”μ²­ν•˜μ§€ μ•Šμ•˜μ„ κ°€λŠ₯성을 κ°„κ³Όν•΄μ„œλŠ” μ•ˆλœλ‹€. μ„œλ²„μ—μ„œλŠ” μ΅œμ†Œν•œ μ΄λŸ¬ν•œ μš”μ²­μ— λŒ€ν•΄μ„œ 였λ₯˜ λ©”μ‹œμ§€ λ˜λŠ” Sentry와 같은 였λ₯˜ 좔적 μ†”λ£¨μ…˜μœΌλ‘œ 뢄석할 수 μžˆλ„λ‘ λ‚¨κ²¨μ•Όν•œλ‹€.

λ§Œμ•½, AWS WAFλ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ μ„€μ •κ³Ό κ·œμΉ™μ— 따라 더블 μŠ¬λž˜μ‹œκ°€ ν¬ν•¨λœ μš”μ²­μ΄ μ„œλ²„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜κΉŒμ§€ λ„λ‹¬ν•˜μ§€ μ•Šμ„ 수 μžˆμŒμ„ λ°±μ—”λ“œ κ°œλ°œμžλŠ” μ•Œκ³  μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.