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('');alert('xss');" />
<br>
<div id="message">Your timer will execute in ');alert('xss seconds.</div>
</body>
</html>
答案 0 :(得分:2)
让您感到困惑的是两种不同语言的混合:HTML和JavaScript。 '
是HTML。在显示并将其解释为JavaScript 时,它会转换为'
字符。这意味着,从JavaScript解释器的角度来看,'
和'
之间没有区别。代码onload="startTimer('');alert('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') || alert('1');
视为startTimer('') || alert('1');
,并且只会运行此脚本。