对反射型和基于 DOM 的 XSS 进行分类

信息安全 攻击 xss javascript
2021-08-24 21:55:48

在引用了 DOM 和 Reflected XSS 之间的差异后 ,我观察到某些攻击可能既是基于 DOM 的,也可能是Reflected XSS我想知道我的理解是否准确,或者它们应该是相互排斥的我有一些我发现在这两个类别中重叠的例子:

网址

反映http://example.com/index.php?user=<script>alert(123)</script>

基于 DOMwww.mywebsite.com/logon.asp?user=<script>MaliciousFunction(...)</script>

身体

反映<body onload=document.getElementById("xsrf").submit()>

基于 DOM<body onload="go()">

重定向

反映<A HREF="javascript:document.location='http://www.google.com/'">XSS</A>

基于 DOMdocument.write('<a href="' + document.location + '?gotoHomepage=1'+ '">Home</a>');

以及许多其他类型的各种反射型 XSS,例如插入图像标签、iframe、HPP 等。我知道对于基于 DOM 的 xss,没有往返网络服务器,并且通常利用 url 中的“#”来写入这个值直接进入网页。

2个回答

我观察到某些攻击既可能是基于 DOM 的,也可能是反射型 XSS

不,您列出的是基于 DOM 和反射 XSS 的相同有效负载(这两种攻击通常以相似的方式被利用)。但是在这之下发生的仍然是基于 DOM 的 XSS 或反射型 XSS(嗯,或者存储型 XSS)。从来都不是两者兼而有之。

不同 XSS 类型的名称并没有说明攻击者将如何攻击某人,而是说明了攻击的工作方式。正如您所指出的,基于 DOM 的 XSS 和反射型 XSS 都可能以相同的方式被利用,例如:

http://example.com/index.php?user=<script>alert(123)</script>

但是使用反射型 XSS,您将拥有一个服务器端脚本,该脚本将接受user参数,然后将其放入返回给用户的 HTML 文档中。

另一方面,对于基于 DOM 的 XSS,浏览器将获取user参数,然后将其放入网页中。

因此,不同之处在于有效负载最终是如何在用户端执行的,而这可能以一种或另一种方式发生。但它不能同时发生在两种情况下*

好吧,从技术上讲,如果服务器和浏览器将有效负载放在网站中,它可以,但这并不是重点。

它们不一定是排他的。他们利用不同的弱点。如果您有能力通过反射攻击进行“传统”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