这是我参与「第四届青训营 」笔记创作活动的的第6天
👋本文分享要点:防御篇( 防御XSS/CSRF/Injection/Dos/中间人的攻击 )
🤔上一篇笔记我们作为攻击者了解到了多种攻击方式,那我们应该怎样去防止别人的攻击呢?
防御XSS攻击
两个要点
- 永远不信任用户的提交内容
- 不要将用户提交内容直接转换成DOM
防御XSS的现成工具
前端
- 主流框架默认防御XSS
- google-closure-library
服务端(Node)
- DOMPurify
😈如果用户需求必须动态生成DOM呢? 😅那就要小心这几个地方了
🚨 1. string ——>DOM
new DOMParser();
这时候我们要对string进行转义
🚨 2. 上传 SVG
<svg>
<script>alert('xss')</script>
</svg>
因为svg标签可以插入<script>标签,所以要对其做一次过滤
🚨 3. 自定义跳转链接
<a href="javascript:alert('xss')" ></a>
尽量不要让用户做自定义跳转链接的行为,如果一定要,就要做好过滤
🚨 4. 自定义样式
只有指定收入的用户选择,才会发出这个get请求,这个用户的收入情况就会暴露给恶意攻击者,所以如果允许这种自定义样式的行为,就要对能够设置URL背景图片、字体文件额外的留意
👋为了下面的内容讲解,先插播讲解一下:Same-origin Policy(同源策略)和Content Security Policy(CSP) 内容安全策略
Same-origin Policy(同源策略)
同源:确保两个URL上的协议、域名、端口号统统相等
一般来说,同源请求都是没有问题的,但如果非同源、跨域的话往往是不可行的,更多的是要看你请求的类型和对应服务器的配置
Content Security Policy(CSP) 内容安全策略
CSP
- 哪些源(域名)被认为是安全的
- 来自安全源的脚本可以执行,否则直接抛错
- 对eval+inline script说❌
防御CSRF攻击
🤔除了Origin+Referrer,还有其他判断【请求来自于合法来源】的方式吗?
先有页面,后有请求:
具体的实现思路:CSRF——token
🚨CSRF——iframe攻击
iframe发出的请求不是跨域请求,而是同源请求,点击了button完成一次CSRF攻击
🤔那我们该怎么防御呢?
有一个http响应头部可以被利用到,具体是指X-Frame-Options响应头部
X-Frame-Options:DENY/SAMEORIGIN
如果可以在服务器进行编码的话,则可以对所有的页面设置这个X-Frame-Options响应头部,有两个值可以选择:DENY/SAMEORIGIN DENY:当前页面不能作为iframe进行加载 SAMEORIGIN:必须是同源的页面才能加载这个iframe
🚨GET !== GET + POST
有时候开发者为了偷懒,将GET请求实现为既能GET(获取数据)又能POST(修改数据)
如果被攻击到了,用户的隐私不仅会被泄露,而且还会被篡改(一石二鸟) 所以一定要避免这种操作!!!
😇再来看看另一种防御CSRF的策略
避免⽤户信息被携带:SameSite Cookie
从根源上解决了CSRF的攻击方式
😇我们来看一下具体SameSite Cookie的含义
限制的是:①Cookie domain②页面域名
🤔那依赖Cookie的第三方服务怎么办?
如:我们做了一个页面,引了一个X站播放器,但因为第三方Cookie不能识别用户登录的状态,导致用户发不了弹幕,用户体验极差,怎么办?
当然,SameSite Cookie已经想到了如何应对这种方式
不对SameSite 做任何限制,但同时标明这个cookie是Secure以确保安全
SameSite vs CORS(跨站资源共享)
防御CSRF的正确姿势
因为防御CSRF的方式很多,case by case防御不太现实,所以防御的正确姿势是先做一个中间件(专门去生成防御CSRF的策略),就在一处完成web的CSRF的防御
防御Injection攻击
- 找到项目中查询SQL的地方
- 使用
prepared statement(将SQL语句进行提前的编译)
除了SQL注入之外,针对其他攻击还有其他的措施
-
最小权限原则
- ❌sudo || root
-
建立允许名单 + 过滤
- ❌ rm
-
对URL类型参数进行协议、域名、ip等限制
- ❌访问内网
防御Dos攻击
针对正则表达式的Dos
- Code Review(❌/(ab*]+/)
- 代码扫描 + 正则性能测试
- ❌用户提供的使用正则
针对DDos
关键的防御思路:
传输层——防御中间人攻击
防御方案:使用HTTPS协议
HTTPS
HTTPS的特性
- 可靠性:加密、(避免了明文传输)
- 完整性:MAC 验证、(确保信息没有被篡改)
- 不可抵赖性:数字签名(确保双方身份可被信任)
HTTPS大概流程(TLS握手)
HTTPS——完整性
接收方会对接受的信息重新进行一次哈希计算,和传递过来的哈希值进行对比,如果两者相等就说明没有被篡改。
扩:数字签名
数字签名的过程:
签名执行者使用私钥对一些指定内容进行一些数学计算,生成一个对应的签名,凡是具有公钥的人都可以都签名进行一次校验,如果是私钥生成的签名,则校验通过
HTTPS——不可抵赖:数字签名
数字签名在HTTPS中是这样工作的: (非对称加密过程中)
- 加密过程:内容 [服务的元信息 + 公钥(sessionKesy)] + CA私钥(进行签名) === 生成 服务器证书 ——>传递到浏览器中
- 验证过程:浏览器用 CA颁发的公钥对证书进行校验 如果校验通过,说明证书合法(证书签发者身份可信)
HSTS
就是如何将HTTP请求升级到HTTPS请求
总结
今天通过防御者的角度去防御XSS/CSRF/Injection/Dos/中间人的攻击,我们要知道:
-
安全无小事
-
使用的依赖(npm package,甚至是NodeJS)可能成为最薄弱的一环
- left-pad 事件
- eslint-scope 事件(npm install 除了带来了黑洞,还可以带来漏洞)
- event-stream 事件
-
保持学习心态