MENU

CVE-2016-4977: RCE in Spring Security Oauth 漏洞分析

October 13, 2016 • Security

受影响的版本

  • Pivotal Spring Security OAuth 2.0 – 2.0.9
  • Pivotal Spring Security OAuth 1.0 – 1.0.5

背景

几个月前,我对一个使用Spring Security OAuth框架进行授权的Web应用程序进行了测试。在我的研究中,我发现了一些问题,包括远程代码执行漏洞。

该Web应用程序使用了广泛适用的框架Spring Security OAuth实现。人们会默认觉得这是安全的,但事实上并不是。然后我发现有几个著名的网站也实施了易受攻击的代码。

Spring Boot Demo (maven)

如果你想自己验证自己的网站是否存在问题,你下载spring boot demo应用程序作为maven项目:http://secalert.net/research/cve-2016-4977.zip

通常人们会通过一个合法的请求来运行demo程序:

http://localhost:8080/oauth/authorize?
response_type=token&client_id=secalert&scope=openid&redirect_uri=http://localhost

一切正常。 然后我开始寻找常见的问题,如XSS:

response_type=token&client_id=secalert&scope=openid
&redirect_uri=<s>XSS</s>

这导致了一个错误,显示:”Whitelabel Error Page”。令人惊讶的是许多知名的网站仍然使用whitelabel错误页面,而不是配置自定义的错误页面。Spring Security OAuth的例子默认情况下发生错误时会显示”Whitelabel Error Page”。Whitelabel视图反映了部分给定的参数值,这导致了XSS。在黑盒测试中发现XSS之后,我并没有马上报告这个问题,而是查看了源代码以确定存在漏洞的代码。在审查源代码时,我意识到有一个更危险的问题存在。

Error Handling调用SpelView

查看源代码:

/* Lines 137-148 of: http://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration.java */

private final SpelView defaultErrorView = new SpelView("Whitelabel Error Page"+ "This application has no explicit mapping for /error, so you are seeing this as a fallback."+ "${timestamp}"+ "There was an unexpected error (type=${error}, status=${status})."+ "${message}");
@Bean(name = "error")
@ConditionalOnMissingBean(name = "error")
public View defaultErrorView() {
    return this.defaultErrorView;}

用户提供的值传递给”org.springframework.security.oauth2.provider.endpoint.SpelView” 类,该类使用”oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java”中的SpelExpressionParser。

Source code: /spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java
...
import org.springframework.expression.spel.standard.SpelExpressionParser;
...
private final SpelExpressionParser parser = new SpelExpressionParser();
private final StandardEvaluationContext context = new StandardEvaluationContext();
...
this.helper = new PropertyPlaceholderHelper("${", "}");
...
Expression expression = parser.parseExpression(name); ...

这非常有趣,Spring表达式语言(单击此处查看详细信息)是spring用于注释中的配置和代码位置的语法。为了检查该参数是否也易受Spring表达式语言注入,我通过以下来测试:

http://localhost:8080/oauth/authorize?
response_type=token&client_id=secalert&scope=openid&redirect_uri=${777-111}

响应消息显示“666”,这意味着POC代码已经进行了测试!

补丁

维护者发布了一个修补程序:http://pivotal.io/de/security/cve-2016-4977

在修补程序中的竞争条件可能被利用

如果一个人审查应用的错误修复(http://github.com/spring-projects/spring-security-oauth/commit/fff77d3fea477b566bcacfbfc95f85821a2bdc2d),可以得出结论,这个修复看起来是一种局部的修复。他们尝试通过使用“org.springframework.security.oauth2.common.util.RandomValueStringGenerator”类替换”{” 前缀来阻止whitelabel视图中的递归占位符。

/* Source code: "http://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java": */
...
public SpelView(String template) {
    this.template = template;
    this.prefix = new RandomValueStringGenerator().generate() + "{";
    this.context.addPropertyAccessor(new MapAccessor());
    this.resolver = new PlaceholderResolver() {
      public String resolvePlaceholder(String name) {
        Expression expression = parser.parseExpression(name);
        Object value = expression.getValue(context);
          return value == null ? null : value.toString();
      }
    };
    }
...
    String maskedTemplate = template.replace("${", prefix);
    PropertyPlaceholderHelper helper = 
    new PropertyPlaceholderHelper(prefix, "}");
    String result = helper.replacePlaceholders(maskedTemplate, resolver);
    result = result.replace(prefix, "${");

这看起来像一个快速的解决方案,但如果攻击者提出足够的请求,但由于竞争条件RCE仍然可以被利用,因为RandomValueStringGenerator(API docs)类生成一个默认长度(6)的字符串。

禁用环境中的Whitelabel错误页

作为网络开发人员或网络管理员,您应该考虑停用whitelabel错误页面使用一个通用的文本自定义错误页。请参考点“77.2自定义的whitelabel错误页:http://docs.spring.io/spring-boot/docs/current/reference/html/howto-actuator.html

Archives QR Code
QR Code for this page
Tipping QR Code