最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How is this XSS attack working? - Stack Overflow

programmeradmin6浏览0评论

SPOILER ALERT: This question contains an answer to one of the problems from the Google's 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. The following is the code from Google's XSS challenge - Level 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). The variable timer carries the input from the user. The goal of this activity is to alert a message by sending a payload which can bypass Django's XSS security.

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? In the onload handler OR within the startTimer() method?

I'm confused because if I check the source HTML of the page after submitting the payload, Django is encoding the payload:

<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>

SPOILER ALERT: This question contains an answer to one of the problems from the Google's 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. The following is the code from Google's XSS challenge - Level 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). The variable timer carries the input from the user. The goal of this activity is to alert a message by sending a payload which can bypass Django's XSS security.

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? In the onload handler OR within the startTimer() method?

I'm confused because if I check the source HTML of the page after submitting the payload, Django is encoding the payload:

<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>
Share Improve this question edited Mar 17, 2017 at 10:45 CommunityBot 11 silver badge asked Jun 9, 2014 at 14:23 Rahil AroraRahil Arora 3,6743 gold badges27 silver badges44 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

What seems to be confusing you is the mix of two different languages: HTML and JavaScript. &#39; is HTML. It's translated to the ' character when displayed and when interpreted as JavaScript. That means, from the JavaScript interpreter's point of view, there's no difference between ' and &#39;. The code onload="startTimer('&#39;);alert(&#39;xss');" is effectively the same as onload="startTimer('');alert('xss');" even though at the first glance it looks like something that shouldn't work.

I see why the XSS worked! One of the section in the OWASP XSS cheat sheet says:

HTML entity encoding is okay for untrusted data that you put in the body of the HTML document, such as inside a tag. 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. So even if you use an HTML entity encoding method everywhere, you are still most likely vulnerable to XSS. You MUST use the escape syntax for the part of the HTML document you're putting untrusted data into. 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. And, the input is being escaped in HTML context (not in JS context). Therefore, JS will treat startTimer('3&#39;) || alert(&#39;1'); as startTimer('') || alert('1'); and will simply run this script.

PS: JS escaping might have prevented the attack.

发布评论

评论列表(0)

  1. 暂无评论