这个XSS攻击是如何工作的?

时间:2014-06-09 14:23:34

标签: javascript django xss

SPOILER ALERT:此问题包含对Google's XSS Challenge中某个问题的回答!如果您现在对了解答案不感兴趣,请继续阅读。


我能够通过level 4 of the challenge,但是,我仍然不知道该漏洞是如何运作的。以下是Google的XSS挑战代码 - 第4级:

<!doctype html>
<html>
  <head>
    <!-- Internal game scripts/styles, mostly boring stuff -->
    <script src="/static/game-frame.js"></script>
    <link rel="stylesheet" href="/static/game-frame-styles.css" />

    <script>
      function startTimer(seconds) {
        seconds = parseInt(seconds) || 3;
        setTimeout(function() { 
          window.confirm("Time is up!");
          window.history.back();
        }, seconds * 1000);
      }
    </script>
  </head>
  <body id="level4">
    <img src="/static/logos/level4.png" />
    <br>
    <img src="/static/loading.gif" onload="startTimer('{{ timer }}');" />
    <br>
    <div id="message">Your timer will execute in {{ timer }} seconds.</div>
  </body>
</html>

基本上,他们使用的是Django框架(which uses a bunch of security measure against XSS)。变量timer携带来自用户的输入。此活动的目标是通过发送可绕过Django的XSS安全性的有效负载来警告消息。

我可以使用以下某个有效负载提醒消息:

');alert('xss

OR

3') || alert('1

我能够使用上述有效负载清除关卡,但我仍然不确定调用alert()方法到底在哪里?在onload处理程序中还是在startTimer()方法中?

我很困惑,因为如果我在提交有效负载后检查页面的源HTML,Django会对有效负载进行编码:

<html>
  <head>
    <!-- Internal game scripts/styles, mostly boring stuff -->
    <script src="/static/game-frame.js"></script>
    <link rel="stylesheet" href="/static/game-frame-styles.css" />

    <script>
      function startTimer(seconds) {
        seconds = parseInt(seconds) || 3;
        setTimeout(function() { 
          window.confirm("Time is up!");
          window.history.back();
        }, seconds * 1000);
      }
    </script>
  </head>
  <body id="level4">
    <img src="/static/logos/level4.png" />
    <br>
    <img src="/static/loading.gif" onload="startTimer('&#39;);alert(&#39;xss');" />
    <br>
    <div id="message">Your timer will execute in &#39;);alert(&#39;xss seconds.</div>
  </body>
</html>

2 个答案:

答案 0 :(得分:2)

让您感到困惑的是两种不同语言的混合:HTML和JavaScript。 &#39;是HTML。在显示并将其解释为JavaScript 时,它会转换为'字符。这意味着,从JavaScript解释器的角度来看,'&#39;之间没有区别。代码onload="startTimer('&#39;);alert(&#39;xss');"实际上与onload="startTimer('');alert('xss');"相同,即使乍一看它看起来像是不可行的。

答案 1 :(得分:1)

我明白为什么XSS有效了! One of the section in the OWASP XSS cheat sheet说:

  

HTML实体编码适用于您放入的不受信任的数据   HTML文档的正文,例如标记内部。它甚至有点儿   适用于属于属性的不受信任的数据,特别是如果   你虔诚地使用属性周围的引号。但HTML   如果您将不受信任的数据放入其中,则实体编码不起作用    标记任何地方,或像onmouseover一样的事件处理程序属性,   或在CSS内部或URL中。即使您使用HTML实体编码也是如此   方法无处不在,你仍然很容易受到XSS的攻击。您   必须使用转义语法作为HTML文档的一部分   将不受信任的数据放入。这就是以下规则的全部内容   约。

在这种情况下,用户输入被输入到事件处理程序中,该处理程序将其视为JS而不是HTML。并且,输入在HTML上下文中转义(不在JS上下文中)。因此,JS会将startTimer('3&#39;) || alert(&#39;1');视为startTimer('') || alert('1');,并且只会运行此脚本。

PS:JS逃脱可能阻止了攻击。