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

140 阅读2分钟

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

Web开发的安全之旅

一.攻击篇

1.Cross-Site Scripting(XSS)

  • 盲目信任用户的提交内容
  • 通常难以从UI上感知(暗地里执行脚本)
  • 窃取用户信息(cookie/token)
  • 绘制UI(例如弹窗),诱骗用户点击 / 填写表单
public async submit(ctx) {
    const { content, id } = cte.request.body;
    //没有对content过滤
    await db.save({
        content,
        id
    });
}
​
public async render(ctx) {
    const { content } = await db.query({
        id:ctx.query.id
    })
    //没有对content过滤
    cctx.body = `<div>${content}</div>`;
}
​
//在这种情况就可以提交**恶意脚本**。
 
//<script>xss</script>

Stored XSS

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

Reflected XSS Demo

  • 对url下手脚
  • 在服务器端注入

DOM-based XSS Demo

  • 对url下手
  • 在浏览器中完成

Mutation-based XSS

  • 利用浏览器渲染 DOM 的特性(独特优化)
  • 不同浏览器,会有区别(按浏览器进行攻击)
  • <noscript><p title="</noscript><img src=x onerror=alert(1)>"
    

2.Cross-site request forgery(CSRF)

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

image-20220801231554819.png CSRF--GET

<a href="#">点我抽奖</a>
​
<img style="display:none;" src="#"/>

CSRF--beyond GET

<form action="#" method="POST">
    <input name="amount" value="10000000000" type="hidden"/>
    <input name="to" value="hacker" type="hidden"/>
</form>

3.Injection

SQL Injection

image-20220801232045942.png

public async renderForm(ctx) {
    const {username,form_id } = ctx,query;
    const result = await sql.query(`
        SELECT a,b,c FROM table
        WHERE username = &{username}
        AND form_id = ${form_id}
    `);
    ctx.body = renderFrom(result);
}
fetch("/api",{
    method:"POST",
    headers:{
        "Content-Type":"application/json"
    },
    body: JSON.stringify({
        username:"any:DROP TABLE table;",
    })
})
​
//删库跑路

Injection 不至于 SQL

  • CLI

  • OS command

  • Server-Side Request Forgery(SSRF),服务器端伪造请求

    • 严格而言,SSRF不是 injection ,但原理类似

4.Denial of Service(DoS)

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

正则表达式——贪婪模式

const greedyRegExp = /a+/; //有多少匹配多少个
const nonGreedyRegExp = /a+?/; //有一个就行
const str = "aaaaaa";
console.log(str.match(greedyRegExp)[0]); //"aaaaaa"
console.log(str.match(nonGreedyRegExp)[0]); //"a"

基于正则表达式的DoS

image-20220801233927472.png Distributed DoS(DDoS)

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

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

image-20220801234314009.png

5.传输层

中间人攻击:

image-20220801234431868.png

二.防御篇

1.XSS

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

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

现成工具:

前端:主流框架默认防御XSS,google-closure-library

服务器端(Node):DOMPurify

【用户需求】不讲武德,必须动态生成DOM的话:

  • 对svg扫描
  • 不做用户自定义跳转,如果要需要检查
  • 用户自定义样式的话,要对url等地方额外注意

Same-origin Policy 同源策略

  • 协议 http/https
  • 域名
  • 端口

2.Content Security Policy(CSP)

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

3.CSRF的防御

image-20220802152805145.png