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

一、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 函数,再 一加载,回调就被触发,数据到手。

二、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 的核心问题就一句话:它能让任意第三方站点读取目标站点的认证态数据。
具体利用链:
- 受害者在浏览器里登录了
https://目标站点,会话 Cookie 仍有效。 - 攻击者诱导受害者访问
https://attacker.com/exploit.html。 - 该页面通过
<script src="https://目标站点/api/me?callback=steal">发起请求,浏览器自动带上目标站点的 Cookie。 - 目标站点返回
steal({"id": ..., "email": ...})。 - 攻击者页面上预先定义的
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 渗透测试代理工具)抓包后按以下步骤判断:
- GET/POST 调用里搜
?callback=、?jsonp=、?cb=:URL 里出现这类参数就是现成的 JSONP 端点。 - 手动追加 callback:拿到任意返回 JSON 的端点(比如
/api/user/1001),在 URL 后面追加?callback=anything,看响应是否变成anything({...})。 - 改 format 参数:看到
?format=json时改成?format=jsonp,观察响应内容是否变成函数包裹形式。 - 观察 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/jsonphttps://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。














暂无评论内容