一、全称

跨站脚本攻击(Cross Site Scripting)

二、原理

通过在网站中的输入框写入 script 脚本或引入 script 文件,如果网站未过滤输入内容,将会解析该脚本。

如果脚本的功能是获取网站的 cookie,cookie 中又保留一些敏感信息,则后果有可能很严重。

三、类型

  • 反射型攻击:脚本当作 url 的参数进行注入执行

  • 存储型攻击:脚本被存储到 DB 后,读取时被解析执行

四、注入点

# 4.1 HTML 节点

页面代码:

  1. <div>${content}</div>

content 的内容为 <script>alert(1)</script>,脚本攻击后,会变成:

  1. <div><script>alert(1)</script></div>

页面将会执行 alert(1)。

# 4.2 HTML 属性

页面代码:

  1. <img src="${imgSrc}" />

imgSrc 的内容为 2" onerror="alert(2),脚本攻击后,会变成:

  1. <img src="2" onerror="alert(2)" />

页面将会执行 alert(2)。

# 4.3 Javascript 代码

  1. <script>
  2. var mydata = "${data}";
  3. </script>

data 的内容为 hello";alert(3);",脚本攻击后,会变成:

  1. <script>
  2. var mydata = "hello";alert(3);"";
  3. </script>

页面将会执行 alert(3)。

# 4.4 富文本

富文本需要保留 HTML 文本,HTML 文本中就有 XSS 攻击的风险。

五、防御

浏览器自带一些防御能力,但只能防御 XSS 反射类型攻击,且只能防御上文描述的前二个注入点。

防御手段原理也很简单,就是将可能会执行脚本的标签或属性进行转义和过滤。

# 5.1 HTML 节点的防御

将 < 和 > 转义成 &lt; 和 &gt;。

# 5.2 HTML 属性的防御

将 " 转义成 &quto;。

# 5.3 Javascript 代码的防御

将 " 转义成 \“ 。

# 5.3 富文本的防御

使用白名单保留部分标签和属性。

需要前端第三方工具:cheerio

案例:

  1. function xssFilter(html) {
  2. var cheerio = require("cheerio");
  3. var $ = cheerio.load(html);
  4. // 白名单列表,key:标签,value:属性
  5. var whiteList = {
  6. "img":["src"],
  7. "a":["href"],
  8. "font":["color","size"]
  9. };
  10. // html 的遍历所有元素
  11. $("*").each(function(index,elem) {
  12. // 删除不在白名单的标签
  13. if (!whiteList[elem.name]) {
  14. $(elem).remove();
  15. return;
  16. }
  17. // 删除不在白名单的标签的属性
  18. for (var attr in elem.attribs) {
  19. if (whiteList[elem.name].indexOf(attr) == -1) {
  20. $(elem).attr(attr,null);
  21. return;
  22. }
  23. }
  24. });
  25. return $.html();
  26. }

还有另一种第三方工具,名字就叫 xss