什么是 XSS

XSS(Cross-Site-Scripting),跨站脚本攻击,因为缩写和 CSS 重叠,被别人抢先了,所以只能叫做 XSS

攻击者可以利用这种漏洞在网站上注入恶意的客户端代码。若受害者运行这些恶意代码,攻击者就可以突破网站的访问限制并冒充受害者。

如果 Web 应用程序没有部署足够的安全验证,那么,这些攻击很容易成功。浏览器无法探测到这些恶意脚本是不可信的,所以,这些脚本可以任意读取 cookiesession tokens,或者其它敏感的网站信息,或者让恶意脚本重写 HTML 内容。

XSS 的分类

存储型

持久化,代码是存在服务器(数据库)中的,例如一些文本输入(博客内容,评论内容等)的地方,加入代码,如果没有做相应的过滤,则当用户访问这些页面的时候,会触发这些代码,比较危险。

反射型

非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。

可能发生的危害

这里简单举个例子:我们有个博客服务,支持评论的功能,现在评论了如下内容:

<p style="color:red;">你这篇文章写的真不错,祝火</p>

在这里插入图片描述

如果没有做转义,在进行渲染的时候,则会出现一串红色的字,这看似好像对安全没啥影响。

这可不见得,如果我们输入如下这段呢:

<a href="javascript:alert('霓虹灯');">是兄弟就来砍我</a>

这时,只要我们点击这个 a 标签,就会执行相应的脚本,弹出 ‘霓虹灯’ 三个大字,能够执行脚本了,那操作空间就大了。

目前有很多的产品会将登录后的 token 或者其他一些验证信息放在客户端的 cookie 或者 localStorage 进行存储。这时如果我们没有做 XSS 的防御措施,攻击者就很容易直接让浏览器带着 cookie 去访问服务器(服务器由于识别到了认证信息,则会放行),这里涉及到另一个 web 攻击 CSRF(本篇不做讲解)。

例子

这里简单的给个纯前端的例子,模拟评论,代码很简单,仅演示用,因为使用的是 innerHTML 插入数据,所以可以使用上述的 XSS 攻击。

<html>
<head>
    <style>
        .txrow {
            flex-direction: row;
            width:50%;
        }
        #cmtInput {
            width:100%;
            height:100px;
        }
    </style>
    <script>
        function comment() {
            let input = document.getElementById("cmtInput")
            let c = document.getElementById("cmtContent")

            let newDiv = document.createElement("div")
            newDiv.innerHTML = input.value
            c.appendChild(newDiv)
        }
    </script>
</head>
<body>
    <div style="display:flex;">
        <div class="txrow">
            <textarea id="cmtInput"></textarea><button onclick="comment();">评论</button>
        </div>
        <div style="width:10px;"></div>
        <div class="txrow" id="cmtContent"></div>
    </div>
</body>
</html>

可输入字符串如下:

<a href="javascript:alert('倚天剑999');">是兄弟就来砍我</a>

<img onerror="alert(123)" src="fsd"/>

在这里插入图片描述

XSS 检测

  1. 使用通用 XSS 攻击字符串手动检测 XSS 漏洞。
  2. 使用扫描工具自动检测 XSS 漏洞,如:ArachniMozilla HTTP Observatory等。

预防

  • 前端渲染界面时,尽量使用模板引擎自带的 html 转义功能避免使用 createElement 等类型的方法。
  • 后端在存数据入库时,在相应的数据上也最好做些限制,转义后入库,例如:昵称,邮箱,简介等的长度限制,字符限制等。
  • 尽量避免内联事件中直接使用数据,例如:onload="go('{xxx}')"
  • 时刻保持警惕 在插入位置为 DOM 属性、链接等位置时,要打起精神,严加防范。
  • 提前做 XSS 自动检测和发现,寻找漏洞。

总结

为什么说一些网站上的弹出广告(一刀999)不要去点,特别是已经登录过的网站,个人信息的泄露等都很有可能是从这里泄露的。

由于 XSS 这种攻击手法是很常见且基础的方式,目前大多数的 web 框架都对其做过适配了,我们也不需要太过担心这种安全问题,但是还是要知道有这么回事,并能够有相应的处理方案。

现在大多数的项目都是前后端分离的,前后端都要对 XSS 有所了解,在实际开发中需要多考虑下这类安全问题。

参考

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐