前端 | 青训营笔记

67 阅读5分钟

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

Web开发的安全之旅

Web安全一窥

Web安全这个概念实际上比我们想象的要常见的多,比如说在谷歌搜索引擎搜索data leak关键词,就能随随便便搜到上亿条搜索结果。

安全问题“很常见”,会危害用户的隐私,公司的利益受损,最重要的也可能导致我们程序员丢工作,所以我们一定要重视。

两个角度看Web安全

  • 假如你是一个hacker——攻击
  • 假如你是一个开发者——防御

攻击篇

要点:

Cross-Site Scripting(XSS)跨站脚本攻击

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

XSS主要利用了

XSS=盲目信任用户的提交内容+string→DOM

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

XSS的一些特点

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

XSS的性质——1.Stored XSS

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

比如说,假如某个视频网站存在一个XSS漏洞,有人上传一段视频,之中插入了一个XSS的恶意脚本,那当用户看这个视频的时候,所有观看这个页面的用户都会被XSS攻击到,所有的用户的隐私信息都可能被泄露,那么电商、网商可能就会搜到你的一个爱奇艺的账户,而且你还有可能被账户踢出,就是这么可怕。

XSS的性质——2.Reflected XSS

  • 不涉及数据库
  • 从URL上攻击
host/path/?param=<script>alert('123')</script>

XSS的性质——3.DOM——based XSS

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

(与上相同的URL)

Reflected vs DOM——based

Reflected XSS和DOM——based XSS其实很类似,但它俩有一个非常重要的区别,就是完成注入脚本的地方。反射型恶意脚本其实是在Server也就是服务端注入,而基于DOM的XSS攻击实际上是完全由浏览器这一侧来完成整个闭环。 image.png

XSS的性质——4.Mutation——based XSS

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

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

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

demo

image.png

CSRF——GET

<a>
<img>
<form method="POST">
<input type="hidden">

Injection

SQL Injection

image.png

Injection不止于SQL

  • CLI
  • OS command
  • Server-Side Request Forgery(SSRF),服务端伪造请求
    • 严格而言,SSRF不是Injection,但是原理相似

Denial of Service(DoS)

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

正则表达式——贪婪模式

重复匹配时「?」 vs 「no?」:满足“一个”即可vs尽量多

ReDoS:基于正则表达式的DoS

贪婪:n次不行?n-1次再试试?——回溯

响应时间延长

接口吞吐量下降

Distributed DoS(DDoS)

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

「不搞复杂的,量大就完事儿了」

攻击特点
  • 直接访问IP
  • 任意API
  • 消耗大量带宽(耗尽)
demo

image.png

传输层

中间人攻击

image.png

为什么会发生?

①明文传输

②信息篡改不可知

③对方身份未验证

防御篇

XSS

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

XSS——现成工具

前端
  • 主流框架默认防御xss
  • google-closure-library
服务端(Node)
  • DOMPurify

XSS——耗子尾汁

!!【用户需求】不讲武德,必须动态生成DOM002EC909.png

1.!!string→DOM
new DOMparser();
2.!!上传svg
<svg>
  <script>alert("xss");</script>
</svg>
3.!!自定义跳转链接
<a href="javascript:alert('xss')"></a>
4.自定义样式

image.png

插播:Same-origin Policy

image.png

Content Security Policy(CSP)

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

CSRF的防御

image.png

CSRF——token

除了Origin+Referrer,其他判断【请求来自于合法来源】的方式

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

先有页面,后有请求 image.png ①用户绑定:攻击者也可以是注册用户===可以获取自己的token

②过期时间:【前向保密】

CSRF——iframe攻击

image.png

CSRF anti-pattern

GET!==GET+POST

image.png 所以,我们以后在写代码的时候一定要避免偷懒行为,我们一定还是要按照功能去把各个接口按照职责划分开,应该是GET的行为就是get的请求,应该是POST的请求就是单独另外一个接口,一定要区分开。

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

image.png

image.png
限制的是:

①Cookie domain

②页面域名

依赖Cookie的第三方服务怎么办?

内嵌一个X站播放器,识别不了用户登录态,发不了弹幕

Set-Cookie:SameSite-None;Secure;

SameSite vs CORS

image.png

防御CSRF的正确姿势

从node这一层角度来讲,我们应该应该做一个中间栈,这个中间栈就专门去生成各种防御CSRF的策略,就在余处保证我们整个Web app都能完成对CSRF的防御。

Injection

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

Injection beyond SQL

image.png

Regex DoS

image.png

DDoS

image.png

传输层——防御中间人

image.png

HTTPS的一些特性

image.png

HTTPS的大致流程

image.png

HTTPS——1.完整性

image.png

数字签名

image.png

HTTPS——不可抵赖:数字签名

image.png

HTTP Strict-Transport-Security(HSTS)

image.png

Subresource Integrity(SRI)

image.png

demo

image.png

补充

image.png

尾声

  • 安全无小事
  • 使用的依赖(npm package,甚至是NodeJS)可能成为最薄弱的一环
    • left-pad事件
    • eslint-scope事件
    • event-stream事件

!!npm install除了带来了黑洞,还可以带来漏洞

  • 保持学习的心态