Practical JSONP Injection

Introduction

JSONP 全称: JSON with Padding. 它的出现是为了 bypass Same-Origin Policy.

假设 http://mybank.com 提供了 API 接口供 mobile 读取 transaction 信息,并以 JSON 格式返回.

{
    "transactions": [{
        "transactionId": "1",
        "amout": 100,
        "date": "2017-02-01"
    }, {
        "transactionId": "2",
        "amount": 200,
        "date": "2017-02-02"
    }]
}

然而, 由于 SOP 的关系, 在 http://evil.com 上, 我们不能通过 XMLHttpRequest 来调用该 API, 以此获取敏感信息.

不过假如API返回的不是JSON, 而是一个 callback function 的话, Injection 就有机会了.

myCallBack({
    "transactions": [{
        "transactionId": "1",
        "amout": 100,
        "date": "2017-02-01"
    }, {
        "transactionId": "2",
        "amount": 200,
        "date": "2017-02-02"
    }]
})

Exploit

众所周知, script 是不受 SOP 的限制, 于是我们可以在页面http://mybank.com 上调用 //mycdn.com/script.js.

类似地, 我们将 API endpoint 作为 js 加载在页面上.

<script type="text/javascript">
  function myCallback(data){
	alert(JSON.stringify(data));
  }
</script>
<script src="http://mybank.com/gettransaction"></script>

Bonus

  • 假如X-Content-Type-Options: nosniff, Content-Type must be set to JavaScript.
  • 假如API Endpoint 有做 referrer 检查, 我们可以通过
  • data URI scheme
  • 如果目标page 支持 http, 只要我们 evilpage 用 https, evilpage load 目标 page 就不会带 referrer 过去.

Modern Browser 自带mixed-content security mechanism. https load http 页面会失败.

Mitigation

用 CORS

  • completely remove JSONP functionality
  • add the Access-Control-Allow-Origin header to your API response
  • use cross-domain AJAX requests

Ref

Practical JSONP Injection – Security Café

Show Comments