JSONP Hijackin 的中文意思是 JSON 劫持, 而能产生 JSON 数据劫持的原因在于前端被跨站攻击了. 跨站 = 跨域, 跨域从字面上理解的话, 就是指超出了范围, 领域. 继续追问一下, 那超出了什么范围? 原来指的范围有多大? 理解跨站攻击的基础在于理解这个域有多大. 为了更准确的理解 JSON Hijackin 攻击, 建议读者可以先了解一下如下几个背景知识:
域概念 (下文会介绍)
JSON (搜索引擎查一下)
接口回调 (建议看我之前的文章: https://www.cnblogs.com/mysticbinary/p/11869181.html)
域概念解释
在计算机领域里很多地方都会用到这个域, 而不同地方所包含的含义却是不相同的, 比如说写代码定义的变量有作用域, 在局域网建设中有网络域, Internet 有一项核心服务是域名解析系统 (DNS). 本文所讨论的域就是指 DNS 的域名.
DNS 的工作原理:
在全球各地有众多服务器 (分布式), 在这些服务器里面都同步的保存着域名和 IP 的一一映射, 这样人们就可以不用记住枯燥的 IP 地址, 只记住有意思的单词域名就行了.
域介绍:
域通过一个点. 来来分开一个域. 域名不区分大小写, 有唯一性, 跟身份证号一样, 是独一无二点.
域分类:
域名又分顶级域名和其它域名, 顶级域名就是如下这些, 被预先定义好的,
可以理解为世界上有一个组织专门在管理, 维护这些顶级域名.
其它域名指二级域, 三级域, 四级域, 五级域 (一般不超过五级域), 二级域就是指靠近顶级域的域名, 如下图:
高级域包含低级域.
各个顶级域名下的二级域名一般需要花钱去申请, 申请到一个二级域之后, 你就可以通过配置 DNS 的 CNAME 记录来配置三级域, 四级域, 五级域的指向.
跨域请求的需求
跨域请求的场景指在前端浏览器发生, 指前端浏览器跨了域名, 端口的请求, 就是跨域请求, 看看我下面的实验:
会发现浏览器为了本地 Cookie 安全的考虑, 都会禁止这种跨域请求的操作. 但是有时一些业务确实会需要到这种跨域请求呀, 比如说百度公司开发了一个 home.baidu.com 站点, 他们想用户已经在本地浏览器登录过了我的首页百度了, 能不能让 home 站点跨域去访问一下 www 站点的接口, 让登录数据互通一下, 避免麻烦用户多次登录的麻烦. 那这个跨站怎么解决呢?
解决方式很多, 下面列举 3 个我知道的:
通过 Nginx 设置反向代理来解决跨域问题.(这里不讨论)
修改响应头方式: Access-Control-Allow-Origin (这里不讨论)
JSONP 方式 (其存在的意义就是绕过同源策略, 来强制执行 XMLHttpRequest(Ajax requests))
JSONP 方式解决跨域请求
JSONP 怎么解决跨域请求? 我没研究那么细, 但是知道这个现象, 就是通过网页的中的 href="https://xxx.xxx.com",src="https://xxx.xxx.com" 这种标签是可以任意进行请求跨域的资源文件的. 也就意味着 JSONP 存在的意义就是绕过同源策略, 来强制执行 XMLHttpRequest(Ajax requests) 的.
JSONP 跨域请求, 通过回调传回前端的案例
前端 HTML 代码:
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
- <script type="text/javascript">
- function jsonpCallback(result) {
- alert(result.a);
- alert(result.b);
- alert(result.c);
- for(var i in result) {
- alert(i+":"+result[i]);// 循环输出 a:1,b:2,etc.
- }
- }
- </script>
- <script type="text/javascript" src="http://crossdomain.com/services.php?callback=jsonpCallback"></script>
后端的 PHP 代码:
- <?PHP
- // 服务端返回 JSON 数据
- $arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
- $result=json_encode($arr);
- //echo $_GET['callback'].'("Hello,World!")';
- //echo $_GET['callback']."($result)";
- // 动态执行回调函数
- $callback=$_GET['callback'];
- echo $callback."($result)";
- ?>
可以看到, 前端先是定义了 jsonpCallback 函数来处理后端返回的 JSON 数据, 然后利用 script 标签的 src 属性跨域获取数据 (前面说到带 src 属性的 HTML 标签都可以跨域), 并且把刚才定义的回调函数的名称传递给了后端, 于是后端构造出 "jsonpCallback({"a":1,"b":2,"c":3,"d":4,"e":5})" 的函数调用过程返回到前端执行, 达到了跨域获取数据的目的.
一句话描述 JSONP: 前端定义函数却在后端完成调用然后回到前端执行!
JSONP 引发的安全问题
JSONP 方式虽然解决了跨域请求, 但是如果使用不当的话, 就会存在有 JSONP Hijackin 劫持攻击问题, 比如说这个场景: 当用户通过身份认证之后, 前端会通过 JSONP 的方式从服务端获取该用户的隐私数据, 然后在前端进行一些处理, 如个性化显示等等. 这个 JSONP 的调用接口如果没有做相应的防护, 就容易受到 JSONP HiJacking 的攻击.
攻击者在他的服务器中制作一个恶意网页, 诱惑用户点击这个网页的链接, 只要这个受害的用户之前登录过某网站, 那么攻击者就能通过这种方式拿到用户的敏感信息.
以 http://api.money.126.net/data/feed/0000002,1399010 这个返回股票信息的 JSON 接口为例, 模拟一下攻击流程.
用户登录了这个网页 (我设置了一个 cookie 为 testcookie=123456 假设用户登录了):
攻击者制作的恶意代码, 诱惑用户点击:
- <HTML>
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
- <script type="text/javascript">
- function hijack(result) {
- console.log(result);
- }
- </script>
- <script type="text/javascript" src="http://api.money.126.net/data/feed/0000002,1399010?callback=hijack"></script>
- </HTML>
用户点击之后, 本地的 JS 脚本就执行了 (说明攻击成功了):
查看一下跨域请求所携带的 cookie:
JSONP Hijacking 怎么检测
查看登录后的个人中心, 需要登录之后才能拿到敏感数据的接口, 这些地方比较容易出现 JSONP 跨域劫持问题, 通过浏览器开发者攻击 F12 的 Network 工具栏, 在 filter 过滤框中输入 xhr,JSONP,call 关键字, 查看结果. 注意有些不是通过回调返回的, 直接看返回 respons.
总结
JSONP Hijackin 和 XSS,CSRF 有相类似的地方, 都是攻击前端用户, 拿到受害用户的敏感数据, 都需要用户点击一次恶意链接才能完成攻击. 不同的是他们的具体攻击方法并不一样.
修复方式
一些敏感的数据接口, 除了了要校验 Cookie, 还要想到前端会受到 CSRF,JSONP Hijacking 攻击的危险, 所以还需要校验 Referer, 一次性 Token 令牌.
参考文章
https://www.cnblogs.com/wlfsky/p/9306731.html
来源: https://www.cnblogs.com/mysticbinary/p/12156992.html