它们不一定是排他的。他们利用不同的弱点。如果您有能力通过反射攻击进行“传统”XSS,那么您可能不需要尝试基于 dom 的攻击,因为您可以在页面加载之前注入您想要的任何代码。
在您的示例中,您是否正在区分根本差异还不是很清楚。
在传统的 XSS 中,您将有效负载作为请求的一部分发送到页面。服务器将您的脚本添加到页面,然后将响应提供给受害者。
基于 DOM 的 XSS 都发生在客户端,例如,JavaScript 直接从 URL、标题、输入字段等读取数据。
例如,您从一个GET请求开始,例如somesite.com/index.php?someVar=foo
我们someVar等于<script>alert(1)</script>
在反射型 XSS 中,变量someVar被服务器读取,然后成为响应页面的一部分。因此,如果有index.php类似的 PHP 脚本:
echo "<h1>Welcome</h1>";
echo $_GET['someVar'];
呈现的 HTML 将是:
<h1>Welcome</h1>
<script>alert(1)</script>
现在实际上,如果攻击者可以放入一个脚本来做他们想做的任何事情。基本上,他们拥有完全的控制权,可以执行他们想要的任何命令。根据代码在流程中执行的时间可能会产生影响,但本质上它们可以控制呈现给受害者的页面。
另一方面,让我们从相同的 URL 开始:
somesite.com/index.php?someVar=foo我们someVar等于 alert(1)
在这种情况下,PHP 文件如下所示:
echo "<h1>Welcome to URL Check</h1>";
echo "<script id="someVar"></script>"
?>
<script>
document.getElementById("someVar").innerHTML = getURLParameter('someVar');
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null
}
</script>
</body>
现在,我承认这是一种非常奇怪的做事方式,但它演示了如何在基于 dom 的上下文和反射上下文中使用相同的输入。
现在肯定有可能出现这样一种情况,即您需要使用基于反射型 XSS 的攻击来利用基于 DOM 的攻击:
同样,假设somesite.com/index.php?someVar=foo我们someVar等于 alert(1)
<?php
echo '<h1>Welcome</h1>';
$someVar = $_GET['someVar'];
echo '<span id="watch1">' . $someVar . '</span>';
echo '<script id="watch2"></script>';
?>
<script>
document.getElementById("watch2").innerHTML = document.getElementById("watch1").innerHTML
</script>
在此示例中,恶意输入作为请求的一部分出现,并且该值被分配给 HTML 的某些部分。然后,当客户端 JavaScript 执行时,它会调用该输入。由于读取输入,实际攻击发生在客户端。这可能不再被认为是最纯粹意义上的基于 dom 的 XSS。
为了防止反射型 XSS 攻击,通常您会在服务器端进行过滤/清理;对于基于 dom 的攻击,您需要在客户端进行过滤/清理,因为客户端直接从客户端的其他地方接收输入。
注意:来自David Morales 的getURLParameter