JSONP跨域漏洞全景:原理、回调反射、检测与白名单防御

导语:JSONP(JSON with Padding,JSON填充)是个上古跨域方案。它利用 <script> 标签不受同源策略限制的特性,把 JSON 数据塞进一个回调函数里”搬”到别的域名去读。这个机制天生没有安全设计,只要接口把 callback 参数原样反射回响应,攻击者就能以 CSRF(跨站请求伪造)风格,把已登录用户的私密数据搬回自己服务器。

JSONP跨域攻击示意

一、JSONP 是什么

JSON(JavaScript Object Notation,JavaScript对象表示法)是 Web 应用里最常用的数据格式,但浏览器同源策略默认不允许跨域读 JSON。两种常见办法能破除这个限制:

  • CORS(Cross-Origin Resource Sharing,跨域资源共享):服务端通过响应头声明允许谁读。
  • JSONP:客户端用 <script> 标签绕开,因为脚本加载不受同源策略限制。

JSONP 是个相当”野路子”的实现:它把 JSON 数据用函数调用包一层,比如 JSON 是 {"hello": "world"},JSONP 就变成 somefunction({"hello": "world"})。读 JSON 的页面只需在全局作用域准备好 somefunction 函数,再 一加载,回调就被触发,数据到手。

JSONP CSRF风格数据窃取流程

二、Callback 参数

“Padding” 这个名字指的就是包裹 JSON 的回调函数名。这个函数名一般由 URL 参数指定,最常见的参数名就是 callback。接口收到这个参数后会原样反射回响应体,比如:

https://目标站点/api/user/info?callback=evil

返回:

evil({"id": 1001, "email": "victim@example.com", "token": "..."})

只要 加载这个 URL,回调 evil 就会被调用,攻击者只需要在自己的页面里定义一个 evil 函数就能接收所有数据。接口对 callback 的过滤直接决定 JSONP 是否沦陷——白名单正则只允许 [a-zA-Z0-9_] 还能挡住一些骚操作,宽松的”匹配字母数字就过”基本等于裸奔。


三、JSONP 的安全风险

JSONP 的核心问题就一句话:它能让任意第三方站点读取目标站点的认证态数据。

具体利用链:

  1. 受害者在浏览器里登录了 https://目标站点,会话 Cookie 仍有效。
  2. 攻击者诱导受害者访问 https://attacker.com/exploit.html。
  3. 该页面通过 <script src="https://目标站点/api/me?callback=steal"> 发起请求,浏览器自动带上目标站点的 Cookie。
  4. 目标站点返回 steal({"id": ..., "email": ...})。
  5. 攻击者页面上预先定义的 steal(data) 函数把 data 通过 new Image().src、fetch、navigator.sendBeacon 等方式发回攻击者服务器。

整个过程和 CSRF 攻击同源——不带凭据窃取,只利用受害者的现成会话。区别在于普通 CSRF 只能”以用户名义发起请求”,JSONP 还能”把响应数据搬回来”,后者杀伤力大得多。

实际漏洞案例:HackerOne 报告 #10373 报告者通过 JSONP 接口拿到了 Twitter 用户的个人信息;Medium 上《Exploiting JSONP and Bypassing Referer Check》一文展示了 Referer(来源页)校验不严时如何跨域利用 JSONP。


四、检测 JSONP 支持

Burp Suite(Web 渗透测试代理工具)抓包后按以下步骤判断:

  1. GET/POST 调用里搜 ?callback=、?jsonp=、?cb=:URL 里出现这类参数就是现成的 JSONP 端点。
  2. 手动追加 callback:拿到任意返回 JSON 的端点(比如 /api/user/1001),在 URL 后面追加 ?callback=anything,看响应是否变成 anything({...})。
  3. 改 format 参数:看到 ?format=json 时改成 ?format=jsonp,观察响应内容是否变成函数包裹形式。
  4. 观察 HTTP 历史:所有响应头里如果出现 Content-Type: application/javascript 而不是 application/json,基本可以确定是 JSONP 端点。

需要特别注意:JSONP 可能作为隐藏特性存在——前端代码没在用,但 API 服务层默默支持,这正是漏报最多的角落。


五、辅助工具

两个常用 JSONP 漏洞利用工具:

  • kapytein/jsonp:命令行 JSONP 漏洞检测脚本,可批量跑 callback 探测。
  • zigoo0/JSONBee:JSONP/CSRF/XSS 一站式 payload(攻击载荷)生成器,按场景分类输出可粘贴进 HTML 的 PoC(Proof of Concept,概念验证代码)。

仓库地址:

  • https://github.com/kapytein/jsonp
  • https://github.com/zigoo0/JSONBee

实战中也可以直接用 Burp 插件 JSONP Hunter 自动扫所有响应里的回调函数模式,效率比手工高很多。


六、防御建议

JSONP 在 2026 年仍是定时炸弹。要么彻底关掉,要么按下面的清单收口:

  • 能停就停:所有 JSONP 端点迁移到 CORS 或同源 fetch,服务端不再反射 callback 参数。
  • callback 严格白名单:固定一个合法的回调名(比如 callback123),不允许客户端指定,任何 ?callback= 参数直接忽略。
  • 正则只允许 [a-zA-Z][a-zA-Z0-9_]{0,31}:单纯字母数字下划线、不能以数字开头、控制长度。这是最低安全基线。
  • 输出 Content-Security-Policy 头:script-src 'self' 'nonce-xxx',禁止 inline(行内)脚本和 eval,从源头切断 JSONP 落地。
  • 敏感接口加 Origin 校验:不依赖 Referer(容易被历史记录或策略绕过),直接看 Origin 头是否在白名单内。
  • 认证态接口用 SameSite Cookie + 双提交 CSRF Token:就算 JSONP 仍存在,CSRF 风格数据窃取也会被双 token 机制卡住。

七、总结

JSONP 是 Web 1.0 时代跨域的妥协方案,它的”安全”完全依赖 callback 参数的反射实现。任何把 ?callback= 直接拼进响应体的接口,理论上都能被任意第三方页面以 CSRF 风格读取登录态数据。CORS 早已是更现代的选择,但大量老 API 仍保留 JSONP 支持——这就是红队测试时不能漏掉 JSONP 检测的原因。

仓库出处:本文基于 learn365 安全学习计划的 day8 翻译扩展,原文仓库 github.com/.../learn365,目录 days/day8.md。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容