乐趣区

关于前端:Web-安全基础

两个角度看 web 平安

如果你是一个 hacker —— 攻打

跨站脚本攻打(XSS,Cross Site Scripting)

  • 歹意脚本注入,<script>...</script>,浏览器将其当成本身 DOM 执行编译
  • 次要利用了

    • 作为开发者自觉信赖用户提交的内容
    • 前端工程师把用户提交的 string 间接转化为 DOM,例如 document.write、element.innerHTML = anyString 等
  • XSS 的一些特点:

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

    • 存储型 XSS(stored XSS)

      • 歹意脚本被存在数据库中
      • 拜访页面 -> 读数据 -> 被攻打
      • 危害最大,对全副用户可见
    • 反射型 XSS(reflected XSS)

      • 不波及数据库
      • 从 URL 上进行攻打
    • 基于 DOM 的 XSS(DOM-based XSS)

      • 不须要服务器的参加
      • 歹意攻打的发动 + 执行,全副在浏览器中实现
      • 与反射型 XSS 的区别在于实现注入脚本的中央:反射型在 server 端、DOM-based 在浏览器端
    • Mutation-based XSS

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

跨站伪造申请(CSRF,Cross-site request forgery)

  • 特点:

    • 在用户不知情的前提下
    • 利用用户权限(cookie)
    • 结构指定 HTTP 申请,窃取或批改用户敏感信息
  • 跨站伪造申请示例

    • 最常见的是利用链接发动 GET 申请(不局限于 GET 申请,结构 HTTP 申请即可)

SQL 注入(SQL Injection)

  • SQL 注入流程

    • 示例

      // 读取申请字段  间接以字符串的模式拼接 SQL 语句
      public async renderForm(ctx){const { username, form_id} = ctx.query;
        const result = await aql.query(`
            select a,b,c from table
            where username = ${username}
            and form_id = ${from_id}
        `);
        ctx.body = renderForm(result);
      }
      
      // 攻击者
      fetch("/api",{
        method:"POST",
        headers:{"Content-Type":"application/json"},
        body:JSON.stringify({username: "any; drop table tabelname;"})
      })
      
      // 造成 select xxx from xxx drop table tablename 删库跑路 

服务端伪造申请(SSRF,Server-site request forgery)

  • 严格上说不是 Injection,然而原理相似
  • 申请用户自定义的 callback URL
  • web server 通常有内网拜访权限

    public async webhook(ctx){
      // callback 可能是内网 url 
      // e.g http://secret.com/get_employ_payrolls
      ctx.body = await fetch(ctx.query.callback);
    }
    // 拜访 callback === 裸露内网信息 

服务回绝(DoS,Denial of Service)

  • 通过某种形式(结构特定申请),导致服务器资源被显著耗费,来不及响应更多申请导致申请挤压,进而产生雪崩效应
  • ReDos:基于正则表达式的 Dos:反复匹配时 ? 与 no ? 满足“一个即可”与“尽量多”

    const greedyRegExp = "/a+/";  // 有多少匹配多少
    const nonGreedyRegExp = "/a+?/"  // 有一个就能够
    const str = "aaaaa";
    console.log(str.match(greedyRegExp)[0])  //aaaaa
    console.log(str.match(nonGreedyRegExp)[0])  //a
  • Distributed DoS:短时间内,来自大量僵尸设施的申请流量,服务器不能及时实现全副申请,导致申请沉积,产生雪崩效应,无奈响应新申请

基于传输层的攻击方式 —— 中间人攻打

为什么产生?

  • 明文传输
  • 信息篡改不可知
  • 对方身份未验证

如果你是一个开发者 —— 进攻

针对 XSS 攻打

  • 永远不信赖用户的提交内容
  • 不要将用户提交的内容间接转换成 DOM
  • 针对 XSS 的现成工具:

    • 前端支流框架默认进攻 XSS
    • google-closure-library
    • 在服务端有 Node.js 提供了 DOMPurify 帮忙实现字符串转译避免 XSS

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

  • 哪些源被认为是平安的
  • 来自平安源的脚本能够执行,否则间接抛错
  • 禁止 eval + inline script
  • 设置形式:

    • 服务器的响应头部

      Content-Security-Policy: script-src 'self'  // 同源
      Content-Security-Policy: script-src 'self' https://domain.com   // 同源加 前面这个能够拜访 
    • 浏览器 meta 标签

      <meta htpp-eqiuv="Content-Security-Policy" content="script-src self" />

CSRF 的进攻

  • 因为其攻击方式是伪造申请,是异样起源,如果限度申请起源,也就限度了伪造申请
  • 具体方法 CSRF —— token
  • iframe 攻打是同源申请,怎么解决

    • 同源的发送申请没方法用 Origin 限度
    • 办法:应用响应头部:X-Frame-Options:deny/sameorigin
  • 防止用户信息被携带:SameSite Cookie

    • 从本源上解决了 CSRF,CSRF 是利用用户权限及 cookie,去伪造本人是该用户来进行歹意操作,如果攻击者无奈获取到用户的 cookie 那就没用方法进行伪造了
    • sameSite 限度的是 cookie domain、页面域名
    • 如果是有 cookie 依赖第三方服务的(例如网站内嵌其余网站的播放器,不登录就没方法发弹幕),能够设置 Set-Cookie: SameSite=None; Secure;
    • SameSite 与 CORS 比照

      • SameSite 进行限度:Cookie 发送、domain 与页面域名
      • CORS 相似白名单:资源读写 HTTP 申请、资源域名与页面域名、白名单
  • 进攻 CSRF 的正确形式 —— 编写中间件

Injection 的进攻

  • 针对 SQL Injection:找到我的项目中查问 SQL 的中央,应用 prepared statement

    PREPARE q FROM 'SELECT user WHERE gender = ?';
    SET @gender = 'female';
    EXECUTE q USING @gender;
    DEALLOCATE PREPARE q;
  • 除了 SQL

    • 最小权限准则,不容许拜访 sudo || root
    • 建设容许名单 + 过滤,不容许进行 rm 这种零碎操作
    • 对 URL 类型参数进行协定、域名、ip 等限度,禁止拜访内网

DoS 的进攻

  • Regex DoS:

    • Code Review,防止贪心模式 /(ab*)+/
    • 代码扫描 + 正则性能测试
    • 不要应用用户提供的正则
  • DDoS:

    • 流量治理:负载平衡过滤、API 网关过滤、CDN 扛量
    • 疾速主动扩容
    • 非核心服务降速

传输层的进攻

  • 应用 HTTPS(HTTP + TLS)
  • HTTPS 的个性:

    • 可靠性:加密,非明文传输
    • 完整性:MAC 验证、禁止篡改、验证 hash
    • 不可抵赖性:数字签名(CA 证书),进行身份验证 — 密码学
  • SRI — Subresource Integrity:避免 CDN 动态资源被篡改
  • Feature / Permission Policy:限度一个页面下,能够应用哪些性能
退出移动版