On Tuesday, February 1, 2017, security vendor Sucuri disclosed a severe vulnerability in the WordPress REST API in versions prior to 4.7.2. The vulnerability allows for remote, unauthenticated and easily automated modification of blog post and page content by manipulating a parameter payload. Sucuri, Inc. notified Akamai of this vulnerability in advance of the public disclosure, which allowed the Threat Research team to internally confirm exploitability and to develop a new rule for Kona Site Defender designed to protect customers from this vulnerability. It's important to understand the new Wordpress REST API before we discuss the technical details of the vulnerability.
What is REST?
REST stands for Representational State Transfer. It is a stateless client-server protocol that is mostly used over the HTTP protocol. You can read about the REST protocol on Wikipedia for more information. In short, REST is used so that other websites, mobile applications, desktop / server software and other components can programmatically retrieve data easily and automatically, without the need to access the website from a browser. This is what allows your information to be communicated across multiple websites as you browse the Internet.
WordPress REST API was first introduced into the WordPress core in version 4.4 back on December 8, 2015. The documentation site gives the following introductory information:
As an example of usage, if we send a GET request to this URL- http://www.some.site/wp-json/wp/v2/posts/ - we will see the following JSON response data:
By using JSON format, the data is easily parsed and consumed by other 3rd party applications.
Updating Blog Content
One use of REST is allowing an authenticated user to create or update a blog post using this new API interface. They could send a POST request using the following example format:
However, if an unauthenticated user was to try to send the same POST request, they would receive a 401 Unauthorized HTTP status code and a JSON error message like the following:
New Security Risks?
A WordPress security company recently released a blog post covering the WordPress REST API and posed the following prophetic question:
Type Juggling vs. Type Casting
The exploitation of this vulnerability relies on the abuse of a programming feature, known as type juggling. Type juggling is where the developer allows the type of data being entered to be determined by its context. Here is a snippet from the PHP documentation:
Compare this to type casting, where the developer to define how the data should be treated:
The PHP documentation also states the following regarding type juggling:
It may not be obvious exactly what will happen when casting between certain types.
That phrase should make PHP developers nervous as it could indicate other problems.
POST Schema Objects
The WP REST API documentation shows the following information for the POST Schema:
Notice the "id" object entry. Although the Schema specified that "id" should contain an integer value, there were locations within wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php and other files where the "id" value was not cast properly as an integer value. The result is that, by including an "id" parameter value in either the query_string or POST payload that contains any non-numeric character, authorization checks can be bypassed.
Exploiting the Type Juggling Flaw
All an attacker needs to do in order to exploit this flaw is to include an "id" parameter value that is not an integer value. Here is an example of a web defacement attack as capture by Burp Repeater:
In the left-hand window pane, you can see a new "id" parameter to the normal JSON request body content. In that parameter field, the included alphanumeric text abuses the type juggling feature in PHP and causes the authentication/authorization checks to fail. The right-hand window shows that the response HTTP status code is 200 OK and the JSON body includes the new blog post content sent in the request. This vulnerability can be used for defacements and/or disinformation by malicious actors.
Modification of blog post or web page content is not the only potential outcome. Remote command execution (RCE) may also be possible, depending upon which WordPress plugins are installed and enabled. This vulnerability has been designated HIGH severity due to the following reasons:
Attack vectors are easily adapted to mass exploitation within scripts
The REST API is enabled by default on all WordPress sites.
WordPress Security Patches
WordPress development team updated its code to fix this vulnerability by adding additional logic to ensure that the "id" parameter values are properly cast as integers. Here is an example of this update code from the official Git repository for version 4.7.2:
Monitoring for Attack Traffic
Once Akamai was made aware of this vulnerability, the Threat Research Team began monitoring data on our Cloud Security Intelligence (CSI) platform to identify if there is evidence of pre-public release 0-day scanning or exploitation attempts. This could indicate that another party besides Sucuri was aware of the flaw and tried to exploit it. We can confirm that although we have seen a few probes for WP Web API endpoints that have non-integer values, we have not seen any indications of exploit attempts for this vulnerability. We will continue, however, to monitor for related traffic once this vulnerability is made public and will report back a status in the near future.
To ensure protection, Akamai Kona Site Defender and Web Application Firewall Customers should:
Enable KRS Rule ID 3000063 to identify and block exploit attempts for this vulnerability.
WordPress Administrators should:
Verify your WordPress version in the Admin panel.
- Check Automatic Updates configurations - https://codex.wordpress.org/Configuring_Automatic_Background_Updates
If you are an Akamai customer, please contact your account representative or Akamai Technical Support (via https://control.akamai.com/ or by calling 1-877-4-AKATEC) if you have any additional questions or concerns.