这是我参与「第五届青训营 」伴学笔记创作活动的第13天
在网络时代下,Web 安全随处可见并且危害极大,Web 安全问题也越来越受到重视。基于此背景,将从安全问题中「攻击者」和防御者的角色出发,讲解目前存在哪些技术手段将危害到 Web 安全。
课堂笔记
视频地址
ppt地址 Web 开发的安全之旅.pptx - 飞书云文档 (feishu.cn)
课程概述
从攻击、防御两个视角,简要介绍前端范畴内常见的安全问题,包括 XSS、CSRF、SQL 注入、DOS 等。
一、本堂课重点内容:
攻击层面和防御层面的XSS、CSRF、Injection、Dos、传输层攻击
二、详细知识点介绍:
01.攻击篇
跨站脚本攻击CSS(Cross-Site Scripting)
攻击者将恶意脚本注入到web网站中,当其他用户访问到就会产生XSS攻击
XSS主要利用了:
1.开发者盲目信任用户提交的内容
2.前端工程师直接把用户提交的字符串转换成了DOM
XSS的特点:
1.通常难以从 UI 上感知(暗地执行脚本)
2.窃取用户信息(cookie / token)
3.绘制 UI (例如弹窗),诱骗用户点击/填写表单
XSS 的分类
存储型 XSS 攻击(Stored XSS)
1.恶意脚本被存在数据库中
2.访问页面->读数据=被攻击
3.危害最大,对全部用户可见
反射型 XSS 攻击(Reflected XSS)
1.不涉及数据库
2.从URL上攻击
恶意脚本在服务端进行注入
基于 DOM 的 XSS 攻击(DOM-based XSS)
1.不需要服务器的参与
2.恶意攻击的发起+执行,全在浏览器完成
恶意脚本在浏览器进行注入
基于 Mutation 的 XSS 攻击(Mutation-based XSS)
1.利用了浏览器渲染 DOM 的特性(独特优化)
2.不同浏览器,会有区别(按浏览器进行攻击)
跨站伪造请求 CSRF(Cross-site request forgery)
1.在用户不知情的情况下
2.利用用户权限(cookie)
3.构造指定 HTTP 请求,窃取或修改用户敏感信息
攻击方式不局限与get请求,攻击者只需要构造一个HTML表单即可
注入(Injection)
假如有一个 HTTP 请求,SQL 参数在请求上带入,这段请求打到了服务器端,服务器端从 HTTP 请求上去读参数。构造出一个SQL语句,去运行这段SQL代码,这段代码被执行之后,也就是被执行到恶意的 SQL 注入,导致攻击者能够获取其他数据、修改数据、删除数据等
服务拒绝 DoS (Denial of Service)
通过某种方式(构造特定请求),导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应
ReDos(基于正则表达式的DoS)
正则表达式——贪婪模式
/a+/ 有多少匹配多少,如aaaaa
/a+?/ 有一个就行,如a
服务器端写了一个贪婪的正则表达式,攻击者可以传入一个容易发生回溯的字符串来攻击,导致服务器端响应时间延长,接口吞吐量降低,用户响应下降
DDos(分布式拒绝服务 Distributed DoS)
短时间内,来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而雪崩效应,无法响应新请求
特点:
1.直接访问IP
2.任意API
3.消耗大量带宽(耗尽)
传输层攻击(中间人攻击)
利用了:
1.明文输入
2.信息篡改不可知
3.对方身份未验证
02.防御篇
XSS的防御
1.永远不信任用户的提交内容
2.不要将用户提交内容直接转换成DOM
现成工具
前端:
1.主流框架默认防御XSS
2.google-closure-library
服务端(node):
1.DOMPurify
如果用户需求是必须动态生成DOM,需要注意那些点?
1.如果要把string直接生成DOM,需要对string进行转译
2.如果允许用户上传svg文件,如图片,要对svg文件进行一次扫描,因为按照规范,svg中可以插入script标签,如果svg图片进行加载,script标签会被执行,也就完成一次xss攻击
3.尽量不要做让用户自定义跳转的行为,如果做要做好过滤,因为如果允许自定义跳转链接的话,可以传递js代码,导致xss攻击
内容安全策略 CSP (Content Security Policy)
同源策略 Same-origin Policy
同源:两个URL上的 协议、域名、端口 都相同
1.哪些源(域名)被认为是安全的
2.来自安全源的脚本可以执行,否则直接抛错
3.对eval + inline script 拒绝
例如:
服务器的响应头部
Content-Security-Policy: script-src 'self' // 同源
Content-Security-Policy: script-src 'self' https://domain.com
复制代码
浏览器meta
<meta http-equiv="Content-Security-Policy" content="script-src self">
复制代码
CSRF的防御
Origin+Referer
如果 伪造请求的来源 是 异常来源,限制请求来源,即可限制伪造请求,通过请求头部的Origin(表明了请求来自于哪个站点。包括且仅仅包括协议、域名和端口)+Referer( 告知服务器请求的原始资源的URI)进行校验
token
如果一个请求来自合法页面,那么服务器一定接受过这个页面的请求,这样服务器在接受这个页面请求的时候可以标识
浏览器先向服务器发出一个页面的请求,服务器接收到这个请求之后,会返回页面以及一个具体的token,之后浏览器在请求任意api的时候,会把这个token带上,服务器端会对这个token进行校验,如果校验不通过直接报错,不返回具体结果,如果校验通过则返回数据
需要注意的两点:
1.token必须和具体用户绑定,才能确保不会被攻击者利用
2.token需要有过期时间,如果被窃取,则之后的请求会被攻击者长时间利用
iframe攻击
没有跨域,是同源请求
如何防御?
对所有的页面设置X-Frame-Options:DENY/SAMEORIGIN响应头部
SameSite Cookie
如果CSRF利用的是用户权限,并且用户权限在页面的cookie之中,那么如果请求不带cookie,就不会有问题。避免用户信息被携带。从根源上解决CSRF的攻击方式。
例如有一个页面,页面对应的域名为A,此时所有domain属性是A的属性,都称为第一方Cookie,也就是SameSite Cookie,所有domain不是A的属性,为第三方Cookie,即非SameSite Cookie,当向域名A发出请求时,所有第一方Cookie都会被带上,而第三方Cookie不会被带。
SameSite Cookie限制的
1.Cookie domain属性
2.页面域名
依赖Cookie的第三方服务怎么办?
如内嵌一个X站播放器,识别不了用户登录态,发不了弹幕
可以使用Set-Cookie:SameSite=None;Secure;
不对SameSite Cookie进行任何形式的限制,并且标明它是安全的
SameSite VS CORS(跨域资源共享)
防御CSRF的正确姿势
不要case by case防御,而是写一个中间件,专门去防御各种CSRF的策略,保证整个web app都能完成对CSRF的防御
Injection的防御
1.找到项目中查询SQL的地方
2.使用prepared statement,将SQL语句进行提前的编译
PREPARE q FROM 'SELECT user FROM users WHERE gender = ?';
SET @gender = 'female';
EXECUTE q USING @gender;
DEALLOCATE PREPARE q;
复制代码
其他注入:
最小原则问题-不要使用sudo || 不要给root权限
建立允许名单+过滤-拒绝rm等高危操作
对URL类型参数进行协议、域名、ip等限制-避免攻击者访问内网
DoS的防御
ReDoS的防御
1.Code Review ,避免写出贪婪匹配
2.使用代码扫描工具+正则性能测试
3.拒绝使用用户提供的正则
DDoS的防御
传输层的防御
HTTPS的一些特性:
1.可靠性:加密(避免明文传输)
2.完整性:MAC验证(确保了信息没有被篡改)
3.不可抵赖性:数字签名(确保了双方身份是可被信任的)
可靠性:
完整性:
不可抵赖性:
服务提供方会把它的服务元信息和公钥使用CA(证书机构)提供的私钥进行签名,生成真正的服务器端保存的证书,证书会传递给浏览器,浏览器根据CA提供的公钥进行证书的校验,如果校验通过,说明证书合法,说明证书签发者身份可信
HTTP严格传输安全协议 HTTP Strict-Transport-Security (HSTS)
使用HSTS策略,来让浏览器强制使用HTTPS与网站进行通信
如何将HTTP主动升级到HTTPS?
需要先有一个HTTPS访问