简体   繁体   English

这种XSS攻击如何起作用?

[英]How is this XSS attack working?

SPOILER ALERT: This question contains an answer to one of the problems from the Google's XSS Challenge ! SPOILER ALERT:这个问题包含了Google XSS Challenge的问题之一的答案! Please stop reading further if you're not interested in knowing the answer right now. 如果您对现在的答案不感兴趣,请停止阅读。


I'm able to get pass the level 4 of the challenge , however, I still don't know how exactly the exploit is working. 我能够通过挑战第4级 ,但是,我仍然不知道漏洞利用的工作原理。 The following is the code from Google's XSS challenge - Level 4: 以下是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>

Basically, they are using Django framework ( which uses a bunch of security measure against XSS ). 基本上,他们使用的是Django框架( 框架针对XSS使用了一堆安全措施 )。 The variable timer carries the input from the user. 可变timer传送来自用户的输入。 The goal of this activity is to alert a message by sending a payload which can bypass Django's XSS security. 该活动的目的是通过发送可绕过Django XSS安全性的有效负载来警告消息。

I'm able to alert a message using one of the following payloads: 我可以使用以下有效负载之一来提醒消息:

');alert('xss

OR 要么

3') || alert('1

I'm able to clear the level using the above payloads but I'm still not sure where exactly the alert() method is being called? 我可以使用上面的负载清除级别,但是我仍然不确定在哪里确切地调用alert()方法? In the onload handler OR within the startTimer() method? onload处理程序中还是在startTimer()方法中?

I'm confused because if I check the source HTML of the page after submitting the payload, Django is encoding the payload: 我很困惑,因为如果在提交有效负载后检查页面的源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>

What seems to be confusing you is the mix of two different languages: HTML and JavaScript. 似乎让您感到困惑的是两种不同语言的混合:HTML和JavaScript。 &#39; is HTML. 是HTML。 It's translated to the ' character when displayed and when interpreted as JavaScript . 显示并解释为JavaScript时,它将转换为'字符。 That means, from the JavaScript interpreter's point of view, there's no difference between ' and &#39; 从JavaScript解释器的角度来看,这意味着'&#39;之间没有区别&#39; . The code onload="startTimer('&#39;);alert(&#39;xss');" 代码onload="startTimer('&#39;);alert(&#39;xss');" is effectively the same as onload="startTimer('');alert('xss');" 实际上与onload="startTimer('');alert('xss');" even though at the first glance it looks like something that shouldn't work. 即使乍看之下它似乎也不起作用。

I see why the XSS worked! 我知道为什么XSS起作用了! One of the section in the OWASP XSS cheat sheet says: OWASP XSS备忘单中的一节之一说:

HTML entity encoding is okay for untrusted data that you put in the body of the HTML document, such as inside a tag. HTML实体编码对于放置在HTML文档正文中的不可信数据(例如,标记内)是可以的。 It even sort of works for untrusted data that goes into attributes, particularly if you're religious about using quotes around your attributes. 它甚至适用于进入属性的不受信任的数据,特别是如果您对在属性周围使用引号表示虔诚的话。 But HTML entity encoding doesn't work if you're putting untrusted data inside a tag anywhere, or an event handler attribute like onmouseover, or inside CSS, or in a URL. 但是,如果您将不受信任的数据放在任何地方的标签内,事件处理程序属性(如onmouseover),CSS内或URL中,则HTML实体编码将无法正常工作。 So even if you use an HTML entity encoding method everywhere, you are still most likely vulnerable to XSS. 因此,即使您到处都使用HTML实体编码方法,您仍然很可能容易受到XSS的攻击。 You MUST use the escape syntax for the part of the HTML document you're putting untrusted data into. 您必须在将不受信任的数据放入HTML文档的一部分中使用转义语法。 That's what the rules below are all about. 这就是以下规则的全部内容。

In this case, the user input is being fed into an event handler, which will treat it as a JS instead of HTML. 在这种情况下,用户输入将被馈送到事件处理程序中,该事件处理程序会将其视为JS而不是HTML。 And, the input is being escaped in HTML context (not in JS context). 并且,输入是在HTML上下文(而不是JS上下文)中转义的。 Therefore, JS will treat startTimer('3&#39;) || alert(&#39;1'); 因此,JS将对待startTimer('3&#39;) || alert(&#39;1'); startTimer('3&#39;) || alert(&#39;1'); as startTimer('') || alert('1'); 作为startTimer('') || alert('1'); startTimer('') || alert('1'); and will simply run this script. 并将仅运行此脚本。

PS: JS escaping might have prevented the attack. PS:逃逸JS可能阻止了攻击。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM