【每日一题NO.77】浏览页面突然出现广告的原因是什么?

前端印记

共 2755字,需浏览 6分钟

 ·

2021-11-09 00:55


问题:在我们访问一个页面时,有时候会突然出现一段广告,这可能是什么原因,怎么解决?

答:可能有两种情况:

  1. XSS跨站脚本攻击
  2. HTTP劫持

什么是 XSS 攻击?

XSS 攻击 一般指攻击者通过在网页注入恶意脚本,当用户浏览网页时,恶意脚本执行,控制用户浏览器行为的一种攻击方式。

他的全称:Cross Site Scripting

他的简称:XSS(因为已经有CSS的称呼,所以改称XSS)

XSS 攻击分类

反射型 XSS 攻击

通过 URL 链接点击触发,是一次性行为, 本质上是服务器端没有对用户恶意输入做安全处理,直接反射输入内容。

如:输入“baidu.com/?id=”,弹出弹窗内容为 1。

谷歌这类安全性高的浏览器基本可以自动处理这类攻击。

存储型 XSS 攻击

顾名思义,一般涉及后端数据存储

常见场景意见反馈模块,这种模块通常用富文本输入,用户可以随意输入内容。
不法分子在前端输入恶意脚本,并通过接口传给后端。
当后台管理系统再次展示反馈意见时,就会读取数据库中这些恶意脚本数据,此时这些数据中含有的攻击脚本就会在浏览者的前端执行,这就是存储型 XSS 攻击。

而且,这种攻击是持久性的。

所以,当我们在项目中使用富文本编辑器、内容编辑器、作用域、文本框等需要用户输入内容的表单时,一定要注意是否有输入内容存在恶意脚本被执行的情况。

这就需要我们在存储给后端时对数据进行转译(将脚本标签转为html的转义字符进行展示)、在读取并展示内容时尽量不要用innerHTML这类用于内容渲染的API。

DOM 型 XSS 攻击

又称作 “DOM反射型XSS”。与第一种“反射性 XSS攻击”的区别是,需要恶意脚本通过操作DOM(比如给DOM元素的innerHTML属性赋值)来进行攻击。

防御

浏览器自带的防御 X-XSS-Protection

目前支持 IE、Chrome、Safari 浏览器,可检测到 XSS 攻击时,阻止页面加载。

使用方式是在HTTP响应头中设置X-XSS-Protection字段:

X-XSS-Protection: 0

X-XSS-Protection 为 0 表示禁止使用 XSS 过滤(不用浏览器自带的安全防护)

X-XSS-Protection: 1

1 表示允许使用 XSS 过滤。

X-XSS-Protection: 1; mode=block

mode=block:若检测到 XSS 攻击,阻止页面加载。

X-XSS-Protection: 1; report=

report=\(仅限 Chromium):若检测到跨站点脚本攻击,浏览器将清理页面并报告违规行为。使用 CSP report-uri 指令发送报告。

HTML 标签

将标签符号<、>等全局转义

const escapeHtml = (str) => {
  str = str
    .replace(/&/g"&")
    .replace(/, "<")
    .replace(/>/g">")
    .replace(/"/g"&quto;")
    .replace(/'/g"'")
    .replace(/ /g" ");
  return str;
};

白名单过滤

大体思路将 HTML 字符串解析成实体对象。
若白名单里属性存在在该实体对象中则做相应的处理。
这里使用 cheerio 将 HTML 解析成实体。

const whiteList = {
  img: ["src"],
};
const xssFilter = (html) => {
  if (!html) return "";
  const $ = cheerio.load(html, {
    normalizeWhitespacetrue,
    xmlModetrue,
  });
  $("*").each((index, elem) => {
    if (!whiteList[elem.name]) {
      $(elem).remove();
      return;
    }
    for (var attr in elem.attributes) {
      if (whiteList[elem.name].indexOf(attr) === -1) {
        $(elem).attr(attr, null);
      }
    }
  });
  return $.html();
};

CSP

CSP(Content Security Policy) 实质就是白名单制度,开发者明确告诉客户端哪些外部资源可以加载和执行。

设置如下:

<meta
  http-equiv="Content-Security-Policy"
  content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:"
/>