【问题标题】:Can malicious javascript code be injected through $()?可以通过 $() 注入恶意 javascript 代码吗?
【发布时间】:2012-06-23 13:29:58
【问题描述】:

例子:

if($('#' + untrusted_js_code).length) > 0
  ....`

通常,“untrusted_js_code”应该是一个简单的字符串,表示项目的 ID。变量的值来自 iframe(通过 postMessage),这就是它不受信任的原因。我只是检查该项目是否存在于当前页面中,然后才对其进行处理。

【问题讨论】:

  • 如果untrusted_js_code 等于例如,最大可能会导致语法错误。 "[some thing]".
  • 为什么在这样的位置使用不受信任的输入?无论如何,如果你想 100% 安全使用 document.getElementById() 而不是像 $() 那样强大的库函数
  • @ThiefMaster 我查看了 jQuery 的源代码,据我所知,选择器实际上应该是安全的(无论如何我都看不到任何 eval)
  • 是的,但是如果你能设法让函数运行它的 create a DOM element 部分而不是 find elements by selector 部分你可以创建例如带有 onload 脚本的图像。

标签: javascript jquery


【解决方案1】:

截至 2012 年 10 月 22 日,jQuery 1.8.2:

是的,XSS 攻击是可能的。

var input = "<script>alert('hello');</script>"
$(input).appendTo("body");

See demo。 jQuery 团队似乎有 acknowledged this 并计划在 jQuery 1.9 中解决它。

从 jQuery 1.8 开始,如果您希望用户输入是 html,请使用 $.parseHTML

var input = "<script>alert('hello');</script>"
$($.parseHTML(input)).appendTo("body");​

See demo,没有警报。


在 OP 描述的情况下,以下内容:

var untrusted_js_code = 'alert("moo")';
$('#' + untrusted_js_code).show();

会翻译成这样:

$('#alert("moo")').show();

这被jQuery解释为CSS选择器,感谢字符串前面的#,相对于html不能有内联JS代码,所以相对安全。上面的代码只会告诉 jQuery 通过该 ID 查找 DOM 元素,导致 jQuery 无法找到该元素,因此不执行任何操作。

【讨论】:

  • 我认为在旧版本中注入脚本(通过包含内联事件的 HTML)是可能的。但也许我将该错误与类似的东西混淆了..
  • @ThiefMaster 你是对的。 1.6.3 之前的版本容易受到一些 XSS 错误的影响,这些错误可能会诱使 jQuery 评估 HTML 而不是选择 DOM 元素。 ma.la/jquery_xss
  • var untrusted_js_code = '&lt;img src="no-such-.gif" onerror="alert()"&gt;'; jQuery( '#' + untrusted_js_code).appendTo("body");;该代码在 jQuery 上发出警报
  • 是的,balpha 在这个问题的另一个答案中指出了这一点;为了以防万一,我在这里添加了他的答案的链接。
  • 再次更新。结果发现 jQuery 1.8.2 仍然存在漏洞,奇怪的是我们错过了这一点。
【解决方案2】:

是的,如果您使用的是旧版本的 jQuery,这在某些情况下是可能的。这已在 version 1.6.3 中修复 (here's the commit)。另请参阅corresponding bug report

提交包含一个澄清问题的测试用例:

jQuery( '#<img id="check9521" src="no-such-.gif"' +
        'onerror="jQuery._check9521(false)">' ).appendTo("#qunit-fixture");

对于 1.6.3 之前的 jQuery 版本,onerror 代码将被执行。

不过,您的特定示例(仅检查长度)没有这个问题。

【讨论】:

    【解决方案3】:

    使用该语句,您要求 jQuery 基于选择器执行查询。 作为选择器的字符串,它不会造成任何伤害。

    【讨论】:

      【解决方案4】:

      这并不像其他人所说的那么清楚。不受信任的代码将无法进行 XSS(只要您有足够新的 jQuery 版本,正如 balpha 指出的那样),但它可以挂起用户的浏览器或使您的代码收到意外的输入。

      例如,如果 untrusted_js_code:input,则翻译为:

      $("#:input")
      

      而 jQuery 似乎只是忽略了 # 并匹配 :input。说真的,打开一个控制台并在这个页面上运行那段代码。 (这似乎只适用于伪类。)

      一个不法分子可能会给你一个计算密集型的选择器(非常简单地:not(.asdf):not(.asdf) 数万次),这需要几秒钟(或几分钟......)来处理。

      (另外,可能存在浏览器错误,因此可能会构造一个选择器来使用户的 Web 浏览器崩溃。)

      【讨论】:

      • 是的,但我们谈论的是发送该变量内容的同一用户。所以他可以随心所欲地让他的浏览器崩溃,我不在乎:)
      • 这是一个公平的观点,在最常见的情况下,用户只能使自己的浏览器崩溃,但如果您要存储 ID 或将其发送给其他人,则可能会出现问题用户。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-07
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多