Web 开发的安全之旅 | 青训营笔记

448 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第4天

以下是我在参加此次青训营课程学习中的一些思考及总结。

Web 安全

我们从两个角度来看 web 安全

  • 假如你是一个 hacker -- 攻击

  • 假如你是一个开发者 -- 防御

攻击篇

XSS 简述

跨站脚本攻击(也称为 XSS)指利用网站漏洞从用户那里恶意盗取信息。

XSS 攻击是指黑客通过“HTML注入”篡改网页,插入恶意的脚本,当用户浏览该页之时,嵌入其中 Web 里面的 html 代码会被执行,从而达到恶意用户的特殊目的。

XSS demo

public async submit(ctx) {
  const { content, id } = ctx.request.body;
  // 没有对 content 过滤
  await db.save({
    contnet,
    id
  });
}

public async render(ctx) {
  const { content } = await db.query({
    id: ctx.query.id
  });
  // 没有对 content 过滤
  ctx.body = `<div>${content}</div>`;
}

XSS 分类

XSS 根据效果可以分为三类:

  1. 反射型 XSS (Reflected XSS)

反射型 XSS 只有在用户访问恶意链接时,才能攻击成功,反射型 XSS 也叫做非持久型 XSS。

demo

Snipaste_2022-08-01_14-28-32.png

public async render(ctx) {
  const { param } = ctx.query;
  ctx.status = 200;
  ctx.body = `<div>${param}</div>`;
}
  1. 存储型 XSS

存储型 XSS 会把用户输入的数据存储在服务器端,这种 XSS 具备很强的稳定性。危害最大,对全部用户可见。

  1. DOM XSS

DOM XSS 与反射型 XSS、存储型 XSS 的主要区别在于 DOM XSS 的 XSS 代码不需要服务端解析响应的直接参与,触发 XSS 的是浏览器端的 DOM 解析。

demo

Snipaste_2022-08-01_14-36-04.png

const content = new URL(location.href).searchParams.get("param");
const div = document.createElement("div");
// 恶意脚本注入
div.innerHTML = content;
document.body.append(div);

XSS 特点

  • 通常难以从 UI 上感知 (暗地执行脚本)

  • 窃取用户信息 (cookie/token)

  • 绘制 UI (例如弹窗),诱骗用户点击/填写表单

CSRF 简述

跨站请求伪造(也称为 CSRF)是一种挟制用户在当前已登录的 Web 上执行非本意的操作的攻击方法。

XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

  • 在用户不知情的前提下

  • 利用用户权限 (cookie)

  • 构造指定 HTTP 请求,窃取或修改用户敏感信息

CSRF demo

Snipaste_2022-08-01_15-11-29.png

防御篇

XSS 防御

  • 永远不要相信用户提交的任何内容

  • 不要将用户提交内容直接转换为 DOM

XSS 现成防御工具

前端

  • 主流框架(React、Vue) 默认防御 XSS

  • google-closure-library

服务端(Node)

  • DOMPurify

【用户需求】必须动态生成 DOM

  1. string -> DOM

使用 new DOMParser() 类似 API 前必须将字符串进行转译。

  1. 允许用户上传 svg

提前扫描 svg 标签,防止中间插入 script 脚本恶意代码。

  1. Blob 动态生成 script

  2. 自定义跳转链接

尽量不要让用户自定义跳转行为,如果做也一定要提前过滤。

  1. 自定义样式

攻击者通过伪造一个 CSS 代码在指定情况下发送一个请求,从而导致攻击。

CSRF 防御

  • 限制请求来源

服务器端开发人员可以校验接收的 Origin 或者 Referer 进行校验,如果是当前服务器的域名那么就放行请求,如果不是则拒绝请求。

  • token

在服务器接收到一个合法页面请求时,服务器可以通过标识来判断是否是一个合法来源的请求。

  • iframe 攻击

限制 Origin,攻击者会使用同源请求来到达攻击。

使用 iframe 来到达绕过 Origin 限制达到攻击。

  • 避免用户信息被携带 SameSite Cookie

CSRF 的攻击是由于携带了用户 cookie,如果不携带 cookie,就从根源上解决了这种 CSRF 攻击。

最后

以上就是我在此次青训营课程 《Web 开发的安全之旅》 中的一些思考和总结。