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๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์ค์ ๊ณผ ๊ท์น์ ๋ฐ๋ผ ๋๋ธ ์ฌ๋์๊ฐ ํฌํจ๋ ์์ฒญ์ด ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ๊น์ง ๋๋ฌํ์ง ์์ ์ ์์์ ๋ฐฑ์๋ ๊ฐ๋ฐ์๋ ์๊ณ ์์ด์ผ ํฉ๋๋ค.