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

97 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的的第5天。 前端的发展、更新迭代是很快的,虽然入门容易,但是要一直走下去,就需要持续不断的学习。只有勇于挑战自己舒适区外的东西,才能不断进步。

web攻击篇

XSS

Cross-Site Scripting(XSS) --- 跨站脚本攻击 在开发维护的页面中,攻击者通过一种方式把他的恶意脚本注入进来

XSS主要利用漏洞

  • 盲目信任用户的提交内容

  • 开发者将用户提交的字符串转换为了DOM

    • document.write
    • element.innerHTML = anyString
    • SSR(user_data) // 伪代码

XSS的特点

  • 通常难以在 UI 上感知 (暗地执行脚本)
  • 窃取用户信息 (cookie/token)
  • 绘制 UI(如弹窗), 诱骗用户点击/填写表单

举例

开发者:

image-20220801160931776

攻击者: --- 可直接提交恶意脚本

image-20220801161040477

XSS攻击分类

Stored XSS

存储型XSS攻击

  • 恶意脚本被存在数据库中
  • 访问页面 -》 读数据 -》 被攻击
  • 危害最大,对全部用户可见
Reflected XSS

反射型XSS攻击

  • 不涉及到数据库
  • 从 URL 上攻击

image-20220801162502495

DOM-based XSS

基于DOM的XSS攻击

  • 不需要服务器的参与
  • 恶意攻击的发起+执行,全在浏览器完成

image-20220801162442560

Mutation-based XSS

基于Mutation的XSS攻击

  • 利用了浏览器DOM的特性(独特优化)
  • 不同浏览器,会有区别(按浏览器进行攻击)

image-20220801162359580

CSRF

Cross-site request forgery(CSRF) --- 跨站回调请求

特点

  • 在用户不知情的情况下
  • 利用用户权限(cookie)
  • 构造指定 HTTP 请求, 窃取或修改用户敏感信息

举例

用户收到一个邮件,邮件里有一个链接,用户点击链接,链接请求银行转账的接口,银行辨认链接的cookie,为合法用户,执行操作,返回结果,钱钱飞了。

image-20220801163546624

Injection

注入攻击

类型:

  • SQL
  • CLI
  • OS command
  • Server-Side Request Forgery(SSRF), 服务端伪造请求(严格来说,SSRF不是injection,但是原理类似)

SQL Injection

image-20220801163833341

demo

开发者

image-20220801164114238

攻击者

image-20220801164129174

DoS

Denial of Service(Dos) --- 服务拒绝

攻击者通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应

ReDoS

基于正则表达式的DoS

image-20220801175855303

DDoS

Distributed DoS(DDoS)

短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而雪崩效应,无法响应新请求(不搞复杂的,量大就完事了)

特点:

  • 直接访问IP
  • 任意API
  • 消耗大量带宽(耗尽)

举例:

洪水攻击 ---- 客户端不断发送请求,服务器依次返回接收确认,客户端不返回确认,TCP握手第三步始终没有执行,于是就一直僵在那里

中间人攻击

  1. 明文传输
  2. 信息篡改不可知
  3. 对方身份未验证

image-20220801181907089

Web防御篇

针对XSS攻击

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

现成工具:

前端

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

服务端(Node)

  • DOMPurify

必须动态生成DOM的话:

  • 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.createObjectURL(blob);
    const script = document.createElement("script");
    script.src = url;
    
  • 自定义跳转链接

    <a href="javascript:alert('xss')"></a>
    
  • 自定义样式

    image-20220801184758947

CSP

Content Security Policy(CSP) --- 内容安全策略

  • 哪些源(域名)被认为是安全的
  • 来自安全源的脚本可以执行,否则直接抛错
  • 对 eval + inline script 说不

服务器的响应头部

image-20220801185047384

浏览器meta

image-20220801185056926

CSRF的防御

image-20220801185202511

CSRF --- token

image-20220801185648862

CSRF --- iframe攻击

image-20220801185814398

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);
}

避免用户数据被携带 --- SameSite Cookie

image-20220801190302777

image-20220801190323282

SameSite vs CORS

image-20220801190420114

防御Injection

找到项目中查询SQL的地方,使用prepared statement

image-20220801190702244

image-20220801190728338

防御DoS

Regex DoS

image-20220801190814613

Logical DoS

image-20220801190902609

DDoS

image-20220801190931701

传输层 -- 防御中间人

image-20220801191018558

HTTPS的一些特性

  • 可靠性:加密

  • 完整性:MAC 验证

    image-20220801191219900

  • 不可抵抗性: 数字签名

    image-20220801191241488

    image-20220801191311351

TLS1.2

image-20220801191138998

HSTS

HTTP Strict-Transport-Security(HSTS)

将HTTP主动升级为HTTPS

image-20220801191522156

SRI

Subresouce Integrity(SRI)

image-20220801191633588

最后

  • 安全无小事

  • 使用的依赖(npm package,甚至是NodeJS)可能称为最薄弱的一环

    • left-pad 事件
    • eslint-scope 事件
    • event-stream 事件
  • 保持学习心态