这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
在开发中,安全问题是不可忽视的。我们可以从两个角度看待web安全
- 假如你是一个hacker————攻击
- 假如你是一个开发者————防御
这篇文章将从防御角度来介绍前端范畴内常见的安全问题,包括 XSS、CSRF、SQL 注入、DOS 等。
XSS
在上篇我们了解到XSS的攻击方式后,我们应该知道永远不能相信用户提交的内容,不要将用户提交的内容直接转化为DOM
前端
- 主流框架默认防御XSS
- google-closure-library
服务端
- DOMPurify
如果用户需求:必须动态⽣成 DOM,那我们要注意在以下几个地方做好过滤:
- string -> DOM
将字符串转换成DOM,我们一定要对这个字符串string进行过滤
new DOMParser()
- 上传svg
用户上传svg,可以内嵌script标签,所以对用户上传的所有svg文件,也要进行过滤
<svg>
<script>alert('xss')</script>
</svg>
- 自定义跳转链接
用户可以自定义跳转链接的话,可以传递js代码,所以对跳转的链接也要进行过滤
<a href="javascript:alert('xss')" >点我</a>
- 自定义样式
如下,通过一个表单,用户点击到指定的按钮,也就是指定收入的用户才会触发,修改背景图片url,这个url就是一个恶意链接,当用户选中就会将用户选中的信息带到恶意第三方,用户信息就泄露了
所以要尽量不要让用户自定义修改样式,如果非要这样,一定要做好过滤
插播 Same-orgin Policy
同源策略是一种非常重要的浏览器安全策略。只有协议、域名、端口号三者都相同,才满足同源。不满足则为跨域。
内容安全策略 Content Security Policy(CSP)
- 那些源(域名)被认为是安全的
- 来自安全源的脚本可以执行,否则直接报错
- 对 eval + inline script 说🚫🚫
CSRF
跨站请求伪造,由于请求来源都是异常的,所以我们可以通过限制请求来源,来限制伪造的请求。
orgin+referer
token
- token必须和具体用户进行绑定
- token需要过期时间,前向保密,保证攻击者获取到历史的token也不能使用
iframe攻击
此时可以使用这个响应头
X-Frame-Options:DENY/SAMEORIGIN
DENY:当前页面不能作为iframe加载
SAMEORIGIN,在同域名页面中才能加载 iframe
这样可以规避一些CSRF攻击
GET !== GET + POST
如上代码,把GET请求和POST请求都当成一个GET请求,那么如果有CSRF请求,那么用户的数据都有可能会被篡改。
要避免这种偷懒行为!!
避免⽤户信息被携带:SameSite Cookie
那么,依赖Cookie的第三方服务怎么办?
防御CSRF的正确姿势
在中间件中防御CSRF
Injection 注入
-
找到项目中查询SQL的地方
-
使用prepared statement
-
最小权限原则
- 禁止
sudo || root
- 禁止
-
建立允许名单 + 过滤
- 禁止
rm
- 禁止
-
对URL类型参数进行协议、域名、ip等限制
- 禁止 访问内网
Regex DoS
- 代码Review,遇到贪婪正则就禁止
- 代码扫描 + 正则性能测试
- 禁止用户提供的正则
DDoS
传输层————防御中间人
HTTP3已经内置了TLS
HTTPS的一些特性
- 可靠性:加密(避免明文传输)
TLS握手过程:
关于详细的TLS握手过程,请看之前文章
- 完整性:MAC 验证(确保信息没有被篡改)
加密的hash值来验证数据的完整性
- 不可抵赖性:数字签名(确保双方身份)
签名的执行者拥有私钥和公钥,私钥自己藏好,公钥是公开可见的
- 加密过程:内容+私钥 进行加密生成 ===> 签名
- 验证过程:拥有公钥的一方对签名进行解密验证,判断签名是否被对应的私钥所加密的,是的话就通过验证
CA证书机构专门来颁发(服务器)证书
数字签名在HTTPS中是这样工作的: (非对称加密过程中)
- 加密过程:内容 [服务的元信息 + 公钥(sessionKesy)] + CA私钥 ===> 生成 服务器证书
- 验证过程:浏览器使用 CA公钥 对 证书 进行验证 如果验证通过,就取出服务器里的公钥(sessionKeys)
浏览器怎么会有这些CA公钥的呢?
CA证书中会包含CA公钥
HSTS
如何开启HTTPS?
在第一次进行HTTPS请求服务器时,服务器返回一个响应头HSTS,下次再用HTTP进行请求时,就会将请求会自动升级成HTTPS协议。
为什么要第一次HTTPS请求才返回这个响应头呢?
因为服务器认为HTTP不安全,所以要等到HTTPS安全的协议才可以返回这样的响应头。所以应该说先有一个HTTPS才有HSTS
SRI
对比hash值
尾声
-
安全无小事
-
使⽤的依赖(npm package,甚⾄是 NodeJS)可能成为最薄弱的⼀环: npm install 除了带来黑洞,还可以带来漏洞
-
保持学习心态