# Web开发常见漏洞防护 本章介绍web开发时常见漏洞的防护方法 ### 点击劫持 简而言之,点击劫持就是攻击者会自己搭建一个网页,这个网页分为两层: - 上层是被iframe导入的被攻击网站,具有一些敏感性操作,比如转账、点赞等按钮,这一层会完全透明 - 下层是攻击者自己精心制作的网页,它会准备一个按钮诱导你进行点击(比如点击领取红包等),当你点击这个按钮时,响应你的将不会是这个按钮,而是上层的转账页面,在不知情的情况下造成财产损失 详情介绍参考:[https://blog.csdn.net/qq_32523587/article/details/79613768](https://blog.csdn.net/qq_32523587/article/details/79613768) 防范点击劫持的最有效做法就是增加响应头:`X-Frame-Options: DENY`, 告诉浏览器我们的网站不可以通过 iframe 进行展示(浏览器收到此响应头的指示之后,会拒绝渲染页面), 从根本上杜绝了点击劫持发生的可能,在 [全局过滤器](/use/global-filter) 章节的示例中,我们已经展示了如何在过滤器中增加安全响应头 响应头`X-Frame-Options`有三个取值: - `DENY`: 任何时候都不可以通过 iframe 展示视图 - `SAMEORIGIN`: 在同域下可以通过 iframe 展示视图 - `ALLOW-FROM uri`: 指定地址来源的访问下可以通过 iframe 展示视图 除了后端的响应头,我们还可以在前端使用如下方式进行判断: ``` js // 判断当前页面是否在顶层视口打开 if(top != window) { // 跳入一个安全页面,比如404页 location.href="xxx"; } ``` 除了跳转页面,你还可以用其它方法防御点击劫持,比如加载一个全局遮罩来隔离用户的点击操作,或者在非顶层窗口下拒绝提交token,使用户保持未登录状态 ### XSS攻击 XSS(跨站脚本攻击)就是指攻击者在一段正常的内容中嵌入恶意脚本,使得访问网页的用户自动运行一些破坏性的代码 例如一个论坛具有发帖功能,攻击者在发帖时故意插入一段如下内容: ``` java ``` 如果论坛服务端没有对此进行任何防护,那么用户每次访问这个帖子的时候都会被强制弹窗, 事实上真正的`XSS攻击`绝不只是弹窗骚扰一下那么简单,它可以完成窃取Cookie,自动转账等破坏性操作 防范XSS攻击: 1. 首先安全响应头给安排上:`X-Frame-Options: 1; mode=block`, 这是浏览器默认提供的XSS防护机制 2. 有条件的情况下,尽量使用前后台分离架构,传统服务端渲染视图时几乎每一个变量都可能成为XSS注入点,而前后台分离下一般只有富文本渲染才会有机会XSS注入 3. 对所有的用户输入必须XSS过滤,特别是字符串型参数 4. 可以使用一些自动扫描工具寻找潜在的 XSS 漏洞 ### CSRF攻击 CSRF(跨站请求伪造),又称 XSRF,攻击流程如下: 1. 用户登陆站点`a.com`,身份令牌被写入Cookie中 2. 攻击者搭建站点`b.com`,引诱用户访问 3. 用户访问`b.com`时,自动执行了攻击者准备的js代码,即:调用`a.com`的转账接口 4. 用户在不知情的情况下,造成了财产损失 仅仅访问一个不安全的站点就让我们造成了财产损失?事实上,真正的CSRF攻击并没有这么简单,挡在攻击者第一道门槛便是`CORS同源策略` 同源策略限制了js在`b.com`中只能操作`b.com`的数据(`Cookie`、`localStorage`、`DOM`等),而无法直接操作`a.com`的数据。 这就导致一个结果:虽然在`b.com`可以调用`a.com`的转账接口,但是却无法携带用户储存在`a.com`的授权Cookie,对于`a.com`来讲,即使收到了浏览器发来的请求, 也因为请求中没有携带token令牌,而无法识别调用者具体是谁,只能将其视为一次无效调用。 但是,请注意!这个小小的限制,虽然为用户提供了安全保护,却也为我们开发者造成了不小的困扰,特别是在前后端分离架构下,我们经常会遇到这个错误: ![https://oss.dev33.cn/sa-token/doc/kuayu.png](https://oss.dev33.cn/sa-token/doc/kuayu.png) 这就是导致无数前端后端互相撕逼的 —— 跨域! 浏览器在检测到你身处`b.com`却想要调用`a.com`的接口时,会率先发送一个`OPTIONS`预检请求,目的是为了询问`a.com`是否同意`b.com`发起的请求, 在默认情况下,`a.com`收到一个陌生的第三方网站发来的请求,做出的回应肯定是:`不允许`, 浏览器收到回应就识相的关闭了请求,跨域请求失败 但是,有些开发者为了省事,直接设置了响应头: `Access-Control-Allow-Origin: *`,允许任何第三方网站的请求,这就给`CSRF攻击`留下了可乘之机 假设我们设置了只允许指定的网站跨域请求,就万事大吉了吗?并没有,攻击者仍可以通过抓包等手段得到我们的转账url, 在`b.com`里,通过`open(url)`直接打开一个新的窗口调用转账接口,由于是属于打开新页面,浏览器连`OPTIONS`预检请求都不会发送,而是直接调用接口成功 此招无解吗?并不。由于它是属于打开新页面,这就导致调用接口时只能发送`get请求`,我们在设计接口时只需要遵守一个准则:`敏感接口一律post,禁止get调用`即可。 究其原因,导致`CSRF攻击`频频发生的原因是什么?是我们在跨域请求时,浏览器总是“自作聪明”的自动提交主站`Cookie`, 在浏览器的不断更新中,Cookie的跨域规则变得愈发复杂,新手开发者及其容易绕的晕头转向,而同时`w3c`对`Cookie`规范的各种修修补补,又总是解决一个问题的同时暴露出其他的N多问题 既然Cookie机制如此难以驾驭,我们何不果断的放弃Cookie机制,改用`localStorage`机制存储会话token,这种方式轻松避免了`自动提交`带来的各种安全问题。 事实上,`localStorage存储` + `header请求头提交`也是前后台分离趋势下的常见会话处理方案 篇幅有限,我们总结一下防范`CSRF攻击`要点 **在Cookie模式下**: 1. 仅靠`CORS同源策略`无法彻底防范`CSRF攻击`,我们必须在后台建立`第三方域名白名单`,只有在白名单中的第三方域名才可以跨域调用我们的接口 2. 涉及到数据增删改类型的接口,必须是`post`模式(或其它),严禁`get`模式,查询接口可以`get` 3. 敏感操作增加验证码或者二次验证密码,减小被攻击的概率 **在 localStorage存储 + header请求头提交 模式下**: 1. 在配置文件中,配置`is-read-cookie: false`,关闭Cookie模式,防止Sa-Token在登录时注入Cookie 2. 同上,敏感操作增加验证码或者二次验证密码,减小被攻击的概率 有关CSRF攻防讲解的比较通透的一篇文章:[https://juejin.cn/post/6844903689702866952](https://juejin.cn/post/6844903689702866952) ### Token泄露 Token泄露一般发生在客户端,比如用户连接了不安全的WiFi导致通讯被监听,虽然此情形下token泄露的责任在于用户,但是我们还是有必要采取一定的措施使其损失降到最低 1. 有条件上https的话一律https 2. token有效期一定不能设置为永久,而且要尽量的短(but:为了不影响用户体验又不能设置特别的短,so: 7-30天是个比较合适的范围) 3. 对敏感操作接口,增加密码二次校验(或手机验证码等) 4. 用户更改密码后使其历史会话直接过期 5. 有条件的情况下后台管理增加踢人下线功能,对已经泄露token的账号可以及时清理下线

更多类型漏洞连载中.... (欢迎提交pr)