[하루한줄] CVE-2022-22978: Spring Security 정규식 필터 우회 취약점
URL
Spring Security RegexRequestMatcher Authentication Bypass Vulnerability Analysis (CVE-2022-22978)
Target
- Spring Security
- 5.5.x ~ 5.5.7
- 5.6.x ~ 5.6.4
Explain
Spring Security는 Spring의 인증과 권한, 인가등 보안을 담당하는 프레임워크 입니다.
접근통제 대상에 정규식을 사용하여 필터링 시 5.6.4 이전 버전 프레임워크에서 이를 우회할 수 있는 취약점이 발견되었습니다.
/*
* web/src/main/java/org/springframework/security/web/util/matcher/RegexRequestMatcher.java
* commit : 708639
*/
public final class RegexRequestMatcher implements RequestMatcher {
...
- private static final int DEFAULT = 0;
+ private static final int DEFAULT = Pattern.DOTALL;
+ private static final int CASE_INSENSITIVE = DEFAULT | Pattern.CASE_INSENSITIVE;
...
}
5.6.3 → 5.6.4 패치내역을 보았을 때 Pattern.DOTALL
이 눈에 띄는데요
Pattern.DOTALL
은 \n
과 같은 개행문자를 포함한 모든 문자와 매칭하는 플래그 입니다.
플래그를 설정안했을 때와 Pattern.DOTALL
로 설정하는 것은 무슨 차이가 있을까요?
이는 UnitTest 코드에서 확인할 수 있습니다.
/*
* web/src/test/java/org/springframework/security/web/util/matcher/RegexRequestMatcherTests.java
*/
@Test
public void matchesWithCarriageReturn() {
RegexRequestMatcher matcher = new RegexRequestMatcher(".*", null);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/blah%0a");
request.setServletPath("/blah\n");
assertThat(matcher.matches(request)).isTrue();
}
@Test
public void matchesWithLineFeed() {
RegexRequestMatcher matcher = new RegexRequestMatcher(".*", null);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/blah%0d");
request.setServletPath("/blah\r");
assertThat(matcher.matches(request)).isTrue();
}
테스트 코드를 보시면 대표적인 개행문자인 \n
과 \r
에 대해서 .*
정규식을 통과하는지 판단하고 있습니다. .*
는 0개 이상의 모든 문자라고 할 수 있는데요. 하지만 모든 문자에 개행문자는 제외하게 됩니다.
이를 이용하여 간단하게 인증우회가 가능합니다.
public class SecurityConfigDemo1 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequest().regexMatchers("/admin/.*").authenticated();
}
}
위와 같이 /admin/
엔드포인트 진입 시 인증을 요구하도록 설계되어있을 때 /admin/%0d
, /admin/%0a
과 같이 개행문자를 집어넣으면 해당 필터에 걸리지 않아 우회할 수 있습니다.
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.