JSON injection

What is JSON injection?

JSON injection is a vulnerability that lets a malicious hacker inject malicious data into JSON streams or use malicious JSON streams to modify application behavior. There are two types of JSON injections, server-side and client-side:

  • Server-side JSON injection happens when data from an untrusted source is not sanitized by the server and is written directly to a JSON stream.
  • Client-side JSON injection happens when data from an untrusted JSON source is not sanitized and is parsed directly using the JavaScript eval function.

Severity: medium severity
Prevalence: discovered rarely
Scope: may appear in all apps that use JSON
Technical impact: privilege escalation, cross-site scripting
Worst-case consequences: full system compromise
Quick fix: sanitize user input, do not use the JS eval function

What is JSON?

JSON (JavaScript Object Notation) is a lightweight data interchange format used for communication between applications. It performs a similar role to XML but is simpler and better suited to processing in JavaScript.

Many web applications use this format to communicate and serialize/deserialize data. Some web applications also use JSON to store important information, such as user data. JSON is commonly used in RESTful APIs and AJAX applications.

What is JSON hijacking?

While JSON hijacking (a subset of cross-site script inclusion – XSSI) also involves the JSON format, it is a slightly different attack, in some ways similar to cross-site request forgery (CSRF). Attackers can use JSON hijacking to intercept JSON data sent from a web server to a web application. A typical JSON hijacking attack might look like this:

  1. The attacker creates a malicious website containing a script tag that references a JSON data URL of the web application under attack and includes code to hijack the JSON data.
  2. A user logged into the targeted web application is tricked into visiting the malicious website (usually using social engineering).
  3. Since the same-origin policy (SOP) allows JavaScript from any website to be included and executed in the context of any other site, the user’s web browser loads the JSON data in the context of the malicious site.
  4. The malicious website hijacks the JSON data.

Example of a server-side JSON injection attack

A simple server-side JSON injection could be performed in PHP as follows:

  1. The server stores user data as a JSON string, including the account type.
  2. User name and password values are taken directly from user input parameters without validation or sanitization.
  3. The JSON string is built using simple concatenation:
$json_string = '{"accountType":"user","userName":"'.$_GET['userName'].'","pass":"'.$_GET['pass'].'"}';
  1. A malicious user appends data to their user name entered into an input form or delivered in an HTTP header. This data is sent to the back-end unsanitized:
john%22,%22accountType%22:%22administrator%22
  1. The resulting JSON string stored by the application back-end is:
{
  "accountType":"user",
  "userName":"john",
  "accountType":"administrator",
  "pass":"password"
}
  1. When reading the stored string, the JSON parser (json_decode) encounters two accountType entries and accepts the last one, granting john administrator privileges without any authentication. Note that, strictly speaking, the behavior of json_decode is not incorrect – RFC-7159 for the JSON format states that “the names within an object SHOULD be unique” but not that they must be unique, leaving some room for interpretation.

Example of a client-side JSON injection attack

A simple client-side JSON injection could be performed as follows:

  1. The initial JSON string is the same as in the previous example.
  2. The server gets the JSON data, including a malicious payload, from an untrusted source and does not sanitize it.
  3. The client parses the JSON string using eval:
var result = eval("(" + json_string + ")");
document.getElementById("#accountType").innerText = result.account;
document.getElementById("#userName").innerText = result.name; 
document.getElementById("#pass").innerText = result.pass;
  1. The accountType value injected by the attacker is:
user"});alert(document.cookie);({"accountType":"user
  1. The eval function executes the alert call.
  2. Parsing the malicious string results in a cross-site scripting (XSS) attack (document.cookie is disclosed).

Potential consequences of a JSON injection attack

The consequences of JSON injection highly depend on the way JSON data is used by the web application. However, in some cases, they may be quite severe:

  • If JSON is used to store authentication data and the app is susceptible to server-side JSON injection, the attacker may gain access to an administrative account in the application. Depending on the privileges of that administrative account, they could then obtain highly sensitive data or perform malicious actions.
  • If a web application is vulnerable to client-side JSON injection, it may be used for attacks that involve reflected XSS, for example, in phishing or spam campaigns.

While JSON injection on its own may not seem very dangerous, it is often only one step in a longer chain of attacks, so in some cases it can have severe consequences, up to and including full system compromise.

How to detect JSON injection vulnerabilities?

The best way to detect JSON injection vulnerabilities varies depending on whether they are already known or unknown.

  • If you only use commercial or open-source software and do not develop software of your own, it may be enough to identify the exact version of the system or application you are using. If the identified version is susceptible to JSON injection, you can assume that your software is vulnerable. You can identify the version manually or use a suitable security tool, such as a software composition analysis (SCA) solution for web applications or a network scanner for networked systems and applications.
  • If you develop your own software or want the ability to potentially find previously unknown JSON injection vulnerabilities (zero-days) in known applications, you must be able to successfully exploit the JSON injection vulnerability to be certain that it exists. This requires either performing manual pentesting with the help of security researchers or using a vulnerability scanner tool that can use automation to exploit web vulnerabilities. Examples of such tools are Invicti and Acunetix by Invicti. We recommend using this method even for known vulnerabilities.

How to prevent JSON injection vulnerabilities in web applications?

As with most vulnerabilities, the key to maintaining web application security and preventing JSON injections is to sanitize data. This applies to both server-side and client-side JSON injections.

To prevent server-side JSON injections, sanitize all data before serializing it to JSON. For example, if you use Java, a good option to sanitize JSON data is to use the OWASP JSON Sanitizer available on GitHub. An even better practice is never to write JSON data manually but always using framework functions that perform sanitization.

The best way of preventing client-side JSON injections is never to use the eval function to evaluate JSON data. Whenever you use the eval function with untrusted data that contains JavaScript code, that code will be executed – and it could be malicious. To eliminate this risk, use JSON.parse instead.

How to mitigate JSON injection attacks?

  • The only way to prevent the severe consequences of server-side JSON injections, apart from scanning for them early in the development cycle, is to design applications so they do not load sensitive information, such as account information and privileges, from user-controlled or otherwise untrusted JSON data.
  • You can completely eliminate the risk of client-side JSON injections by enforcing Content Security Policy, which by default prevents the use of eval. This forces the developers to use the safer JSON.parse method instead.

Frequently asked questions

What are JSON injection attacks?

JSON injection attacks happen when unsanitized JSON data containing a malicious payload is accepted and parsed by a web application or browser. Server-side JSON injection attacks are possible if input data is not sanitized by the server and is written directly to a JSON stream. Client-side JSON injection attacks are possible if incoming JSON data is not sanitized and is parsed directly using the JavaScript eval function.

 

Learn more about the dangers of missing input validation and sanitization.

What is JSON hijacking?

JSON hijacking happens when a malicious web page causes the victim’s web browser to retrieve JSON data from a targeted web application. The web browser then passes the JSON data to a web server controlled by the attacker.

 

Read about cross-site request forgery (CSRF) attacks.

How dangerous are JSON injections?

JSON injections are not very common and not as dangerous as SQL injection or other severe vulnerabilities, but they can still be used in attack chains that lead to other, more dangerous attacks, such as cross-site scripting (XSS).

 

Read more about cross-site scripting (XSS).

ClassificationID
CAPEC153
CWE74, 116
WASC20
OWASP 2021A3

Written by: Tomasz Andrzej Nidecki, reviewed by: Benjamin Daniel Mussler