Recently, Pivotal released a security advisory to reveal the Spring Data REST server is prone to a remote code execution vulnerability (CVE-2017-8046) when processing PATCH requests. Attackers could exploit this vulnerability by sending a crafted PATCH request to the Spring Data REST server. The submitted JSON data contains a SPEL expression, which could cause remote code execution (RCE). Pivotal has released new versions to fix this vulnerability.
Related information is available at the following link:
- Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3
- Spring Boot version < 2.0.0M4
- Spring Data release trains < Kay-RC3
- Spring Data REST 2.5.12, 2.6.7, and 3.0RC3
- Spring Boot 2.0.0.M4
- Spring Data release train Kay-RC3
First, locate the directory in which Spring Data REST resides and then the pom.xml file. Then use the text editor to open the pom.xml file and locate the <parent> label, so as to obtain the current Spring Data REST version. If the current Spring Data REST version is affected, it is prone to the vulnerability.
Pivotal has fixed this vulnerability in such new versions as Spring Boot 2.0.0.M4, Spring Data REST 2.5.12, 2.6.7, 3.0RC3, and Spring Data release train Kay-RC3. Users of the affected versions are advised to upgrade as soon as possible by performing the following steps:
- Locate the directory in which Spring Data Rest resides and use the text editor to open the pom.xml file.
The display varies with versions. You can update the version number setting as required.
- Clear items generated in maven: Open the console to execute the mvn clean command.
- Restart the service: Open the console to enter the Spring Data REST directory and execute the mvn spring-boot:run command.
Use NSFOCUS’s detection product or service to detect the vulnerability:
- For Internet-facing assets, use the emergency vulnerability detection service of NSFOCUS Cloud to check for the vulnerability online. The service is available at the following link:
- For internal assets, use NSFOCUS RSAS V6, WVSS, or IDS to check for the vulnerability:
Remote Security Assessment System (RSAS V6):
Web Vulnerability Scanning System (WVSS):
Network Intrusion Detection System (NIDS):
You should upgrade your devices to the latest version by downloading upgrade packages from the preceding links before using them to detect vulnerabilities.
Use NSFOCUS’s protection product (NIPS, NIDS, NF, or WAF) to protect against the exploitation of the vulnerability:
Network Intrusion Prevention System (NIPS):
Next-Generation Firewall (NF):
Web Application Firewall (WAF):
You should upgrade your devices to the latest version by downloading upgrade packages from the preceding links before using them for protection.
Users can use NSFOCUS WAF to disable the PATCH method for temporary protection. The procedure is as follows:
- Log in to the web-based manager of WAF. Choose Security Management > Policy Management > Basic Protection > HTTP Access Control and then click Create in the upper-right corner of the page.
- Set Action to Block and Source IP Blocking to Unblock.
- Set HTTP Method to Exclude.
4. Click OK to create a policy.
According to the official security advisory, Spring Data REST fails to properly handle PATCH requests, causing arbitrary expression execution that triggers RCE.
As shown in the following patch, the verifyPath method is added to evaluateValueFromTarget to check path validity. If the path is found illegitimate, evaluateValueFromTarget reports an exception and then exits. The whole process is implemented by property.from(pathSource,type) with the basic logic of checking the existence of the path field in bean through reflection.
Reproduction via POC
Visit the following link to find the Spring Data REST project: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples. Then import settings of this project via IDEA. Running this project, you can see that the Jetty service is enabled on local port 8080. Note that this compiled project is of the latest version. To introduce this vulnerability, we need to modify pom.xml to turn the new version to an old one.
Add a dependency plug-in as follows:
Locate the related request from the test directory of the project. Then request http://127.0.0.1:8080/api/cities/1. The echo suggests that the Spring Data REST service operates properly. The POC test results are as follows:
If a previous Spring expression is used as the value of the path field, the following error will be reported:
The preceding figure shows that an error occurs, terminating the ongoing the Spring expression execution. You can see that the path field is indeed polluted, and an expression injection vulnerability exists here.
The POC test is a step away from the real RCE. Check the org.springframework.expression.spel.ast.SpelNodeImpl.setValue method.
The org.springframework.expression.spel.ast.SpelNodeImpl.setValue method throws an exception, indicating that the POC test is some distance from RCE. Looking at setValue implentations, we find that this method is implemented at five places. Previously, we see that the setValue method of SpelNodeImpl throws an exception. Checking their implementations, we notice that only CompoundExpression, Indexer, and PropertyOrFieldReference actually have execution expressions.
Referring to related documents, we learn that CompoundExpression is a complicated expression, each part of which is connected via a dot (.). Indexer is expressed in the format of test[xxlegend]. We observe that such expressions can also execute after their format is changed. Also the call stack is in line with what we understand.
In this POC test, the “op” field is used to specify the action to execute, for which such operation values as “add”, “copy”, “from”, “move”, “replace”, and “test” are defined in the code. Of all the values, “add”, “test”, and “replace” can trigger this vulnerability directly. The following figure shows the call stack of “test”.
We can see that this minor issue is not solved officially, but a restriction is placed, that is, evaluateValueFromTarget will report an error and then exit, preventing getValueFromTarget execution. In this way, RCE is not triggered.