Web开发安全(防御篇) | 青训营笔记

67 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天

讲完了攻击篇,接下来讲解如何进行防御。

XSS 防御

  • 永远不信任用户的提交内容
  • 不要将用户提交内容直接转换成DOM

XSS 现成工具

前端

  • 主流框架默认防御XSS
  • google-closure-library

服务端(Node)

  • DOMPurify

XSS 耗子尾汁

在某些场景下,需要接收用户传入的富文本

string -> DOM

new DOMParser();

上传svg

<svg>
    <script>alert("xss");</script>
</svg>

Blob动态生成script

const blob = new Blob(
    [script],
    { type: "text/javascript" },
);
const url = new URL.create0bjectURL(blob);
const script = document.createElement("script");
script.src = url;

自定义跳转链接

<a href="javascript:alert('xss')"></ a>

CSRF的防御

CSRF的请求来源是异常来源,我们可以通过限制请求来源来限制CSRF攻击。

CSRF的防御.png

CSRF token

if(请求来自合法页面)
then (服务器接收过页面请求)
then (服务器可以标识)

token.png

CSRF iframe攻击

攻击者构造一个页面,页面上有一个<button />标签,用户点击<button />标签时,iframe可能发起一个HTTP请求,并且不是跨域请求,对应的攻击就完成了。

iframe.png

如果我们可以在服务器进行编码,就可以对所有页面设置X-Frame-Options响应头部。它有两个值可以选,一个是DENY,另一个是SAMEORIGIN。通过这种方式可以规避CSRF iframe攻击。

CSRF anti-pattern

GET !== GET + POST

// 将更新+获取逻辑放到同一个 GET 接口
public async getAndUpdate( ctx) {
    const { update, id } = ctx.query;
    if (update) {
        await this.update(update);
    }
    ctx.body = await this.get(id);
}

在写代码时要将GET和POST请求分开。

防御DoS

Regex DoS

  • Code Review
  • 代码扫描+正则性能测试
  • 用户提供的使用正则

Logical DoS

  • 不是非黑即白
    • 有些case,只有在请求量大到一定之后,才会体现
  • 分析代码中的性能瓶颈
    • 同步调用
    • 串行逻辑
    • CPU密集型操作
  • 限流

HTTPS的一些特性

  • 可靠性:加密
  • 完整性:MAC验证
  • 不可抵赖性:数字签名

总结

  • 安全无小事
  • 使用的依赖(npm package,甚至是NodeJS)可能成为最薄弱的一环
  • 保持学习心态