Time-Based PHP V8JS Injection & NoSQL/SSJS Injection

Detecting server-side JavaScript (SSJS) injection vulnerabilities using time-based techniques. Article by Felipe Aragon - February 25, 2012

This article, which is an update of an article that we originally published on December 18, 2011, intends to highlight the risk of unvalidated input used to execute server-side JavaScript.


As you read this, web developers are starting to learn how to use V8Js (Google's V8 JavaScript engine) in PHP, or MongoDB, which is a scalable, high-performance, open source NoSQL database that also allows JavaScript to be used in queries. Today, the most common source of PHP security flaws is unvalidated input. They give rise to SQL Injection, XSS, Remote Command Execution, Local and Remote File Inclusion, etc (known as the PHP Top 5). With the rising adoption of server-side JavaScript, we can expect server-side JS injection vulnerabilities caused by unvalidated user input to become prevalent, and the techniques for exploiting them, commonplace. At Syhunt, we already started a collection of techniques for proactively detecting server-side JS injection flaws.

The Time-Based JS Injection Technique

Injecting a custom sleep code is a technique that may be used to spot injection vulnerabilities in web applications using server-side JavaScript execution. This works with any web system that supports server-side JavaScript execution, such as JavaScript web application frameworks and servers like Jaxer, or PHP with V8Js, or NoSQL engines like MongoDB.

Below you can find examples of server-side JavaScript injection vulnerabilities in PHP that could be spotted using the sleep technique. In the past, we used this same sleep code in the client-side to demonstrate how vulnerabilities we found in the A-A-S (Application Access Server) could be exploited.

Example 1: PHP V8JS Injection Vulnerabilities (PHP + V8Js)

The following requests would make these (or similar) vulnerable web applications sleep for 10 seconds:

vulnerable.php?msg=a';d%20=%20new%20Date();do{cd=new%20Date();}while(cd-d<10000);foo='bar

Vulnerable Code:


$msg = $_GET['msg'];
$v8 = new V8Js();
$v8->executeString("var msg = '$msg'; ..SOME CODE..");

vulnerable.php?msg=version());d%20=%20new%20Date();do{cd=new%20Date();}while(cd-d<10000);foo=('bar'

Vulnerable Code:


$msg = $_GET['msg'];
$v8 = new V8Js();
$JS = <<< EOT
len = print($msg + "\\n");
..SOME CODE..
EOT;

$v8->executeString($JS, 'basic.js');

Example 2: NoSQL SSJS Injection Vulnerability (PHP + MongoDB)

The MongoDB shell provides a sleep() function [1] which makes time-based detection much easier to perform.

The following requests would make these (or similar) vulnerable web applications sleep for 10 seconds:

vulnerable.php?msg=1';sleep(10000);var%20foo='bar

The MongoDB sleep() function works with milliseconds.

Alternative technique using a custom sleep code:

vulnerable.php?msg=1';d=new%20Date();do{cd=new%20Date();}while(cd-d<10000);foo='bar

Vulnerable Code:


<?
$mongo = new Mongo();
$db = $mongo->demo;
$id = $_GET['id'];
$js = "function() {
var id = '$id';
SOME CODE...
}";
$response = $db->execute($js);
...
?>

Example 3: NoSQL SSJS Injection Vulnerability (PHP + MongoDB)

Vulnerable Code:


<?
$mongo = new Mongo();
$db = $mongo->demo;
$year = $_GET['year'];
$collection = $db->demo;
$query = 'function() {var search_year = \'' .
$year . '\';' .
'return this.publicationYear == search_year || ' .
' this.filmingYear == search_year || ' .
' this.recordingYear == search_year;}';
$cursor = $collection->find(array('$where' => $query));
...
?>

Example 4: SSJS Injection Vulnerability (PHP + Jaxer)

Example of a vulnerable application built using the Jaxer Ajax server and PHP.

Vulnerable Code:


<?php
$myVar = $_GET['id'];

echo "<script runat=server>
    myPHPVar = '$myVar';
    onload = function(){
    ..SOME CODE..
    };
</script>";
?>

Example 5: Sleep in JavaScript


var date = new Date();
do { curDate = new Date(); }
while(curDate-date < 10000); // delay time (ms)

SSJS Remote Scanner

We need to think ahead in the future about cyber attacks. This is something that we actively pursue while developing the Syhunt Dynamic scanner. Syhunt Dynamic is the first web application scanner to perform time-based server-side JavaScript injection.

Additional Information

The advent of Big Data and Cloud Computing is driving adoption of NoSQL in the enterprise. Because of this, NoSQL-related vulnerabilities are expected to become much more widespread [2].

In July last year, Bryan Sullivan, a senior security researcher at Adobe Systems, demonstrated server-side JavaScript injection vulnerabilities in web applications using MongoDB and other NoSQL database engines. He demonstrated how they could be used to perform Denial of Service, File System, Remote Command Execution, and many other attacks, including the easy extraction of the entire contents of the NoSQL database -- a blind NoSQL injection attack (paper here ).

Solution

Always validate user input used in server-side JavaScript commands.

Links

Contact