This case-study focuses on the core aspects and utilities of JSON, specifically its escaping method.
SoundCloud.com, such as many others, uses JSON to fetch user-relative information from the server.
The returned data is being escaped (probably) by the JSON escaper mechanism, so any malicious payloads won’t work.
Well, the short answer is no.
The long answer (10 minutes after starting this research) is yes.
At first, I decided to focus on the notifications area (https://soundcloud.com/notifications), where I noticed that ajax requests are being executed when scrolling done (to fetch old notifications).
I have previously inserted some payloads in variant locations on SoundCloud, and analyzed the way the ajax asks for more notifications.
To safely print “bad” characters (‘,”,<,….), the JSON escapes them by putting a \ char before any “bad” character.
And so I started thinking.
What if i’ll do the escaping myself? Will the JSON still escapes it?
Well, it did. The JSON escaper mechanism ‘double-escaped’ payloads that were already escaped. All there was left to do was to pre-escape a payload, which caused to a stored XSS at the notification area.
JSON escaping must be done properly
The only reason why this worked is the assumption of the developers that no one will “pre-escape” their input before submitting it. The JSON mechanism always escaped the input (by adding ” or ‘ chars before it). If you are expecting user’s input to be outputted by a 3rd-party code, you should:
1. Never allow direct use of HTML/Script tags. If you must, allow users to use ‘special chars’ to design their input (such as *bold* instead of <b>).
2. Know the mechanism. JSON adds ” or ‘ before the text. Therefore, if you accept these chars from the user – simply URL encode them.
I’ll use this opportunity to note that the response team of SoundCloud was the fastest one I have ever worked with. Take a loot at the disclosure timeline.
13/02/2016 23:00 – Vulnerability found & reported.
14/02/2016 08:00 – Vulnerability confirmed by Soundcloud.
14/02/2016 14:00 – Vulnerability patched and bounty awarded (HoF + Swag).