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

114 阅读9分钟

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

这是我参加【第四届青训营】笔记创作活动的第10天

网络安全问题很常见,会对用户、公司、程序员(祭天)都造成伤害。因此,了解web开发的安全知识,有效防止网络攻击,对前端工程师来说很有必要。下面,将从两个角度来看web安全。

一、攻击篇

Web安全主要有如下几大分类

  • XSS
  • CSRF(跨站请求伪造)
  • SQL注入
  • 命令行注入
  • DDos注入
  • 流量劫持

(一)、XSS(跨站脚本攻击)

XSS原理:它是指攻击者往web页面或url里插入恶意JavaScript脚本代码且应用程序对用户输入的内容没有过滤,那么当正常用户浏览该页面时,嵌入在web页面的恶意JavaScript脚本代码会被执行,从而达到恶意攻击正常用户的目的。如下图:

image-20220802164559020.png 产生漏洞的两个条件:

  • 盲目信任用户的提交内容。
  • 把用户提交的内容转换为DOM并解析。

XSS的特点:

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

XSS攻击例子如下图:

image-20220802164739126.png

image-20220802164816551.png 两个服务端接口submit(用户提交内容,服务端从用户提交的内容中读取conten字段存取到数据库)和render(用来渲染页面,服务器从数据库db中读取content字段返回给浏览器用于生成html)。 无论是从第一个接口写数据,还是第二个接口读数据,都没有对用户提交的信息做过滤。当攻击者将提交一个script标签作为一个content字段提交到服务器端,当服务器渲染该段内容时,会导致html中插入了一个script标签,攻击者也就完成了一次XSS攻击。

XSS的分类

  • 反射型XSS:它是非持久型,参数型的跨站脚本。
  • 存储型XSS:它是将脚本代码写进数据库可以永久保存数据,危害最大。
  • DOM型XSS:与反射性相似,但是DOM是树形结构,利用DOM标签。
1.存储型XSS攻击-Stored XSS(会被存储到数据库中)

特点:

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

image-20220803152314211.png

2.反射性XSS攻击——Reflected XSS

特点:

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

image-20220803152335214.png

3.基于DOM型(DOM-based XSS)
  • 不需要服务器的参与
  • 恶意攻击的发起+执行,全在浏览器中完成

image-20220803152527970.png

Reflected XSS vs DOM-based XSS

两者有点类似,但有一个重要的区别:完成注入脚本地方不同

  • Reflected XSS 是在服务端这里注入脚本
  • DOM-based XSS是在浏览器这里注入脚本

image-20220803152720031.png

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

image-20220804204204007.png

如图,如果把<noscript><p title="</noscript><img src=x onerror = alert(1)>"> 进行渲染的话,就会变为第二张图的效果,发现<p title="会作为noscript标签的内容,而<img src=x onerror = alert(1)>会作为正常标签进行渲染,src属性不符合规范,所以会触发onerror事件,回调一触发,完成这种XSS攻击。

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

特点:

 1.在用户不知情的前提下
 2.利用用户权限
 3.构造指定的HTTP请求,窃取或修改用户敏感信息

image-20220804204445351.png

如上图,用户收到了一封邮件,里面有个链接,他点了一下,去访问了一个恶意的页面,在这个页面中攻击者构建了一个攻击请求,向银行发起一个转账,而这个请求实在另外一个域名,银行服务器(server A)接受到了这个请求,发现请求上有用户的cookie,而且验证通过,认为该请求合法,然后就执行转账操作,完成转账返回结果,最后用户平白无故的丢失了一笔钱。可以发现整个过程,用户没有访问银行的页面,但对应得转账接口却被请求了,且请求成功,这就是跨站伪造请求。

image-20220804205137539.png

image-20220804205151718.png 注入(Injection)

SQL Injection

image-20220804205227306.png

1读取请求字段

2直接以字符串的形式拼接SQL语句

image-20220804205439827.png

image-20220804205516492.png

执行以上代码,达成删库跑路成就。

解决方法:

  • 正确使用get(只用于查看,列举,展示等不需要改变资源属性的时候) post(用于form表单提交,改变一个资源的属性或做一些其他事情,如数据库增删改)和cookie
  • 非GET请求中,为每个用户生产一个cookie token
  • POST请求的时候使用验证码
  • 渲染表单的时候,为每个表单加一个 csrfToken,然后在后端做 csrfToken验证
  • 校验请求来源
  • 设置cookie samesite

Injection不止于SQL

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

执行

image-20220804205922703.png

image-20220804205932060.png

读取+修改

image-20220804205951344.png

image-20220804210002175.png

(三)、服务拒绝(DOS)

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

插播:正则表达式———贪婪模式

image-20220804210134412.png

ReDoS:基于正则表达式的DoS

image-20220804210146709.png

如图,服务器写了一个贪婪的正则表达式,攻击者传入一个容易发生回溯的字符串abababababab...b通过正则试图匹配上ababababababa,第一次发现不行,回溯,又不行,又回溯...这样导致服务器的响应时间大大延长,导致结果吞吐量明显降低,响应用户的次数大大下降。

Logical DoS

耗时的同步操作;数据库写入;SQL join;文件备份;循环执行逻辑

Distributed DoS(DDoS)

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

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

用于通信的ICMP消息不需要明确的端口号,避免被IDS检测到——TFN2K

哪里阻止DDoS,哪里就受到攻击——防火墙

源IP地址可以伪装,但攻击路径不能伪装——防火墙过滤进出的伪造源IP地址的数据包。所以攻击一旦进行之后,要立即瓦解网络,防止追踪

IP溯源技术只能追踪到攻击者所在的网关

image-20220804210516829.png 如图,攻击者构造大量的SYN给服务器,服务器会返回ACK,SYN,但攻击者此时不会返回第三次ACK,导致第三次握手未完成,连接数不能被释放,从而很快服务器达到最大连接次数,所有的新请求都无法响应,完成一次洪水攻击。

(四)、基于传输层攻击方式———中间人攻击

image-20220804210731713.png

二、防御篇

(一)、XXS防御

  • 永远不要信任用户提交的内容,即不要直接将用户内容转为动态DOM,而是用String形式储存。
  • 当用户应用需求需要使用到动态DOM时间,应该设置逻辑对上传DOM和解析DOM进行转义 / new DOMOarse()
  • 对于svg文件的上传应该尤其的注意防护,svg文件可以内嵌js脚本 <svg><script>alert("xss")</script></svg>
  • 尽量不要允许用户自定义跳转(JS)、自定义样式也不行。
现成工具:

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

服务端(Node):DOMPurify

  • 同源请求策略:

    • 前端请求时应该保证与服务器的安全策略一致。
    • 同源请求策略要求网页所在目录与请求接口域名一致,不一致则会发生跨域(CORS安全策略)。
    • 对eval+inline script不生效
Content Security Policy(CSP)

哪些源(域名)被认为是安全的;

来自安全源的脚本可以执行,否则直接抛错;

对eval+inline script说NO!

image-20220804211555535.png

  • 服务器响应头部'

    Content-Security-Policy:script-src 'self' //同源

    Content-Security-Policy:script-src 'self' http://domain.com"//支持跨域

  • 浏览器meta

(二)、CSRF安全防御

  • 通常网络请求有四种防御策略

    • if 伪造请求 === 异常来源
    • then 限制请求来源
    • Origin 同源请求中,不发送GET+HEAD
    • Referer
  • CSRF - token防护

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

    • 先有页面,后有请求

      • if 请求来自合法页面
      • then 服务器接受页面请求
      • then 服务器可以识别
    • token验证是通过唯一的加密信息码与用户绑定,每次请求都需要将这个加密码随着请求发送到服务器,服务器解密比对信息后判断是否是用户本人操作。

    • token验证码会设置过期时间,避免token泄露。

  • CSRF - iframe 攻击

    • 当Origin被限制时,攻击者会将请求包在内作为子页面,即可突破同源
  • CSRF 防护

    • 避免GET接口和POST接口合并等偷懒行为
    • 防护SameSIte Cookie信息泄露,SameSite Cookie依赖于第三方的Cookie请求,需要允许第三方域名采集Cookie.
    • 防御CSRF需要注意逐级施加权限限制

image-20220804211756899.png

Inject Protection

  • SQL防护

    • 最小原则:避免使用sudo || root 命令
    • 建立ip白名单,拒绝异常rm操作
    • 对URL类型参数、域名、IP加逻辑检验,限制异常请求———防范内网被突破

(三)、防御DoS攻击:

  • ReDoS

    • 减少允许用户使用正则表达式请求
    • 增加校验, 对代码做扫描 +正则性能测试
  • L-DoS

    • 限流: 限制流量的异常波动,对于异常IP封锁。
    • 并不是非黑即白: 有时候需要请求量超过阈值才能检测出L-DoS
    • 分析代码的性能瓶颈:同步调用、串行逻辑、CPU密集操作
  • DDoS

    • 过滤:负载均衡、API网关
    • 抗量:CDN、快速扩容、 非核心服务降级

(四)、传输层———中间人防御

  • HTTP特性: 可靠性-明文加密,完整性:MAC验证;不可抵赖性-数字签名
  • HTTPS加密:在三次握手时进行hash加密,利用公钥和证书进行数字签名校验。
  • 将HTTP主动升级到HTTPS:需要之前要有一次HTTPS访问
  • 当静态资源被劫持篡改了,可以运用SRI对资源做hash验证。

(五)、一点点补充内容

image-20220804214804932.png 安全无小事

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

    • left-pad事件;
    • eslint-scope事件;
    • event-stream事件;npm install除了带来黑洞,还可以带来漏洞
  • 保持学习的心态

推荐读物

image-20220804215352993.png