产生原因:
输入换行符则绕过权限校验的正则匹配。默认的java Pattern模式,不开启DOTALL时候,在默认匹配的时候不会匹配r n 字符。
漏洞代码
org.springframework.security.web.uti.matcher.RegexRequestMatcher#matchers
public final class RegexRequestMatcher implements RequestMatcher {
private static final int DEFAULT = 0;
private static final Log logger = LogFactory.getLog(RegexRequestMatcher.class);
public RegexRequestMatcher(String pattern, String httpMethod, boolean caseInsensitive) {
this.pattern = Pattern.compile(pattern, caseInsensitive ? Pattern.CASE_INSENSITIVE : DEFAULT);
this.httpMethod = StringUtils.hasText(httpMethod) ? HttpMethod.valueOf(httpMethod) : null;
}
public boolean matches(HttpServletRequest request) {
if (this.httpMethod != null && request.getMethod() != null && this.httpMethod != HttpMethod.resolve(request.getMethod())) {
return false;
} else {
String url = request.getServletPath();
String pathInfo = request.getPathInfo();
String query = request.getQueryString();
if (pathInfo != null || query != null) {
StringBuilder sb = new StringBuilder(url);
if (pathInfo != null) {
sb.append(pathInfo);
}
if (query != null) {
sb.append('?').append(query);
}
url = sb.toString();
}
logger.debug(LogMessage.format("Checking match of request : '%s'; against '%s'", url, this.pattern));
return this.pattern.matcher(url).matches(); //匹配模式问题
}
}
Pattern.compile方法
public RegexRequestMatcher(String pattern, String httpMethod, boolean caseInsensitive) {
this.pattern = Pattern.compile(pattern, caseInsensitive ? 2 : 0);
this.httpMethod = StringUtils.hasText(httpMethod) ? HttpMethod.valueOf(httpMethod) : null;
}
第一个参数表示要编译的表达式,
第二个参数则是指定表达式的具体匹配模式,具体可选值有
CASE_INSENSITIVE, MULTILINE, DOTALL, UNICODE_CASE, CANON_EQ, UNIX_LINES, LITERAL, UNICODE_CHARACTER_CLASS and COMMENTS
-
DOTALL:表示更改.的含义,使它与每一个字符匹配(包括换行符n),
-
默认情况下, 正则表达式中点(.)不会匹配换行符,
设置了DOTALL模式, 才会匹配所有字符包括换行符。 -
CASE_INSENSITIVE:忽略大小写。
在RegexRequestMatcher中由于第一个构造方法caseInsensitive设置为了false,所以此处的值为0 代表使用默认状态。
第一个构造方法
public RegexRequestMatcher(String pattern, String httpMethod) {
this(pattern, httpMethod, false);
}
修复
RegexRequestMatcher.java文件的修复是增加了对换行符的匹配以及忽略大小写
测试代码
/admin/.* 用于匹配以 /admin/ 开头的字符串,并且可以匹配任意字符的组合.
/admin/* 只匹配精确的 /admin/* 字符串
public static void main(String[] args) {
int DEFAULT =Pattern.DOTALL;
String str="/admin/.*";
Pattern p =Pattern.compile(str);
String test="/admin/11"+"n";
System.out.println(p.matcher(test).matches());// outcome:false
Pattern p1=Pattern.compile(str,DEFAULT);
System.out.println(p1.matcher(test).matches());// outcome:true
}
参考:
https://www.cnblogs.com/TT0TT/p/16652577.html
原文始发于微信公众号(天才少女Alpha):CVE-2022-22978 漏洞分析
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论