原文:https://www.exploit-db.com/docs/english/45563-client-side-injection-on-web-applications.pdf

简介


我们都知道,Web应用程序或网站通常都需要与用户进行交互。例如,在论坛网站中,一方面,所有信息都共享给来自不同位置的用户或同一个新闻网站的不同用户,另一方面,用户也可以对每篇新闻或文章进行评论,并且这些评论对于其他人来说也都是可见的。

因此,不应该允许用户在数据库中存储危险的数据,同时,开发人员和网站管理员还应该确保将Meta字符从用户输入的表单数据中清除掉,这些都是非常重要的。

目前,针对客户端的攻击技术已经非常丰富了。但是,在这篇文章中,我们只为读者详细解释下列攻击技术。

HTML注入漏洞


当黑客能够将HTML标签注入表单并最终将其存储到数据库中时,就会出现这种类型的漏洞。

想象一下,假设我们有一个博客,用户可以在我们的博客文章中分享他们的评论。如果存在HTML注入漏洞的话,黑客就能够将HTML标签写为评论,并且所有人都可以看到这些代码。大家都知道,利用HTML标签,黑客可以执行下列恶意操作:

如果HTML注入与其他攻击相结合,则:

在本节中,我们只解释HTML注入攻击,其他的攻击方式,我们将在下文中详细加以介绍。

下面,让我们用图例来阐释HTML注入漏洞。

假设我们有一个带留言簿的网站,允许用户与其他人分享他的评论。下图展示了该网站的评论部分:

现在,我们想要将html代码存储到数据库中,而不是纯文本的评论中。下面,我们尝试将以下html代码作为合法的评论提交给系统。

<b><i>Hi this is an html code</i></b>

结果如下图所示:

如您所见,评论是以HTML格式存储的。

实际上,我们可以通过HTML代码来发布大量内容,例如,我们可以发布图像,甚至可以使用iframe标签在这个页面中加载其他网站,并进行丑化攻击。

下面,我们将在评论部分加载图片。

<img src="YOUR IMAGE URL">

结果如下图所示:

如果图像的大小为2MP或更大的话,则可以借助于CSS注入技术来完成相应的丑化攻击,具体细节,将在后文加以解释。

如何缓解HTML注入攻击?


如果您是程序员,并且要在您的网站上修复该漏洞,那么,您只需过滤相应的Meta字符,并将其转换为相应的实体名称即可。

请注意,如果您没有使用任何框架(例如Django、Laravel...)的话,则需要手动执行上述处理。在参考文献中,提供了一个指向完整编码表的链接。但就目前而言,最常用的代码是:

字符      实体编号        实体名称        描述
"   &#34;       &quot;      引号 
'   &#39;       &apos;      撇号(在IE中不起作用) 
&   &#38;       &amp;       &<   &#60;       &lt;        小于号 
>   &#62;       &gt;        大于号

因此,如果将Meta字符转换为实体名称,那么浏览器就不会在客户端解析HTML代码,而只显示纯文本格式的相应编码了。

我在含有该漏洞的网站上进行了尝试,结果如下:

CSS注入漏洞


在上一节中,我解释了HTML注入攻击。接下来,我们将为读者介绍CSS注入攻击。大家都知道,CSS是用于定义网页样式的,包括定义在不同设备和屏幕尺寸上显示时,相应的设计、布局和变化情况。这就意味着,如果我们发现了一个含有HTML注入漏洞的网页,我们就可以通过CSS注入攻击来修改注入的HTML元素样式。例如,如果我们将恶意HTML代码与CSS结合使用,则可以修改图像大小并使用图像覆盖所有网页屏幕,从而成功完成了相应的丑化攻击。

相应的代码如下所示:

<img style=”padding:1000px;” width=”500px;” height=”500px;” src=”OUR-IMAGE-URL”>

有时,当应用程序从用户提供的URL导入样式表,或者在没有进行全面的转义处理就将用户的输入内容嵌入CSS块中时,就会导致CSS注入攻击。

例如,下面就是一段含有相应漏洞的代码:

<a id="input">Click me</a>
<script>
if (location.hash.slice(1)) {
document.getElementById("input").style.cssText = "color: " +
location.hash.slice(1);
}
</script>

这是易受攻击的URL:

https://www.url/#red

加载URL后,我们将根据相应的网页样式标签来渲染页面:

<style>
#input{
color: red;
}
</style>

现在,我们可以在URL的末尾注入我们的CSS。例如,如果我们加载以下URL:

https://www.url/#red; padding:1000px; font-size:70px; background-color:#000000

这意味着,我们将额外的CSS代码注入到了样式标签中。加载这个URL后,样式标签将变为:

<style>
#input{
color: red;
padding:1000px;
font-size:70px
background-color:#000000;
}
</style>

在某些情况下,我们甚至可以从外部源导入CSS文件。

例如:

https://www.url/#red; @import "https://externalsource/navigation.css"

如何缓解CSS注入攻击


为防御CSS注入攻击,应该禁止用户通过嵌入方式向CSS块中添加代码,除非经过了严格的转义处理。因此,在将用户的输入嵌入到CSS块之前,请确保已对其进行了充分的转义处理,并可以考虑使用白名单来防止加载任意样式表。

最后,可以使用以下最佳实践步骤来缓解该漏洞,具体如下所示:

客户端URL重定向漏洞


客户端URL重定向(也称为开放式重定向),这实际上是一种输入验证漏洞,当应用程序接受用户控制的输入时,导致攻击者可以在该输入中指定可能导致恶意攻击的外部URL的链接。这个类型的漏洞可用于进行网络钓鱼攻击或将受害者重定向到感染页面。

当应用程序接受可能包含URL值的不可信输入而不对其进行消毒处理时,就会出现这种漏洞。因为其中的URL值可能导致Web应用程序将用户重定向到另一个页面,例如,由攻击者控制的恶意页面。

通过将不受信任的URL输入修改为恶意站点,攻击者就能够进行网络钓鱼诈骗,从而窃取用户的相关凭证。由于重定向是由真实应用程序发起的,因此,网络钓鱼尝试可能看上去非常值得信赖,因此更具有迷惑性。

例如,我们不放看看下面的JavaScript代码:

<script>
var redir = location.hash.substring(1);
if (redir)
window.location='http://'+decodeURIComponent(redir);
</script>

注销后,上面的代码会将用户重定向到另一个内部页面。

相应的URL为:

http://url/?#www.url/login

在这个易受攻击的代码中,脚本没有通过查询字符串对包含用户提供的输入的“redir”值进行任何安全检查,这意味着攻击者可以通过提交以下URL将受害者重定向到网络钓鱼站点:

http://url/?#www.attackerurl/phising-page

因此,在注销之后,用户将重定向到恶意URL,而不是登陆页面。

如何缓解客户端URL重定向攻击


程序员可以通过检查传递给重定向函数的URL来防止这种攻击。程序员应确保该函数中的所有URL都是相对路径,即以单个“/”字符开头的路径。(以//开头的外部URL将由浏览器翻译为协议、绝对URL——因此,程序员也应拒绝这类URL。)

如果程序员需要执行外部URL重定向,他也应该考虑为所有外部URL建立相应的白名单。

同样,对于第二层防御,程序员应该检查重定向过程中HTTP请求头部内的Referrer是否与域名匹配。

基于DOM的客户端脚本漏洞


Dom型XSS也是一种XSS攻击,对于这种攻击来说,相关的有效载荷是通过修改网页DOM元素来注入的,这意味着客户端代码会意外地运行。

对于前面介绍的攻击,即HTML注入攻击和URL重定向攻击,都可以与Dom型XSS攻击结合使用。例如,在HTML注入攻击中,我们可以通过下面的有效载荷来利用Dom型XSS漏洞:

<img src='some-link' onerror=alert(1)>

结果如下所示:

在客户端URL重定向攻击中,可以使用下面的有效载荷来攻击Dom型XSS漏洞:

http://www.url/?#javascript:alert(document.cookie)

请注意,在这种情况下,易受攻击的JavaScript代码为:

<script>
var redir = location.hash.substring(1);
if (redir)
window.location='http://'+decodeURIComponent(redir);
</script>

另一个DOM型XSS示例

假设我们有一个网站,其中包含一个用于修改网站语言的表单。此外,我们还有一个用于处理该表单的JavaScript函数。

相应的JavaScript代码为:

<select><script> document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf(" lang=")+8)+"</OPTION>"); document.write("<OPTION value=2>English</OPTION>"); </script></select>

下面是用于修改语言的URL:

http://www.url/page.php?lang=French

从上面的JavaScript代码可以看出,这里会使用GET方法从URL中载入lang参数,因此,如果改变lang参数的值,页面的语言将通过JavaScript函数进行修改。这意味着,我们可以将JavaScript恶意有效载荷注入到lang参数的值中。

例如,可以使用URL中的有效载荷来攻击DOM型XSS漏洞,具体如下所示:

http://www.url/page.php?lang=<script>alert(document.cookie)</script>

如何缓解基于DOM的客户端脚本攻击


如果需要动态地将HTML代码加载到Dome元素中的话,应使用下面的函数进行HTML编码:

另外,为了添加另一层安全防护,对所有不受信任的输入,可以通过下面的函数进行JavaScript编码处理:

同样,对于第一个示例来说,通过缓解HTML注入攻击和客户端URL重定向攻击也有助于防御Dom型XSS攻击。

感谢大家耐心读完本文,祝大家阅读愉快!

参考文献


  1. https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet
  2. https://portswigger.net/blog/detecting-and-exploiting-path-relative-stylesheet-import-prssivulnerabilities#badcss
  3. https://www.owasp.org/index.php/Testing_for_Client_Side_URL_Redirect_(OTG-CLIENT-004)
  4. https://portswigger.net/kb/issues/00501300_css-injection-reflected
  5. https://www.owasp.org/index.php/Testing_for_CSS_Injection_(OTG-CLIENT-005)
  6. https://www.hacksplaining.com/prevention/open-redirects

源链接

Hacking more

...