“互联网本来是安全的,自从有了研究安全的人之后,互联网就变得不安全了。”
安全一直是互联网中比较重视的问题,一个安全事件可能会给企业带来巨大的利益和声誉上的损失。但这点也是在日常开发或产品设计中容易疏忽的东西,在此总结一下我在web安全上一些浅显的理解以及日常防范措施。
常见的web安全问题
越权
越权顾名思义就是越过自身权限,可操作本不属于自己权限范围内的功能。
越权也是日常开发中容易出现的安全漏洞。
横向越权
同一级别权限, 可以访问其他用户数据。
如:普通用户A可以看到普通用户B的转账记录,属于横向越权。纵向越权
不同级别权限, 可访问更高/不同角色用户数据。
如:普通用户可查看财务专员才能看的财务报表,属于纵向越权。
防御措施
- 权限统一平台管理,代码统一将所有权限维护在一处。
- 做好不同场景角色的自测,包括web界面测试和接口权限测试。
- 在敏感操作前,应该设计二次安全验证,如审批,验证码等。
- 登陆态设置合理过期时间,所有请求都必须校验好登陆凭证是否合法。
- 在多个服务/模块的情况下, 做好认证, 非认证范围内的服务/模块不允许访问。
跨域漏洞
对前端比较熟悉的同学都知道,浏览器在安全功能上有个同源策略。
何为同源?即同个ip,端口,协议。默认情况下,在源网站下不允许跨域访问资源。
允许跨域访问资源的标签
script,img,iframe,link这些带src属性的标签比较特殊,是允许访问跨域资源的,相当于是对浏览器发起了一个get请求。
为什么需要同源策略
对跨越有初步认识后,可以设想一种情况,如果没有同源策略,那么有可能网站A的一段JavaScript脚本对网站B做了改动,但实际上网站B并没有引入网站A的脚本。那这就是一个安全漏洞了。
但随着互联网的发展,许多公司业务开始变复杂庞大,跨域又几乎是大家都要面临的问题。如我们工作中经常需要访问第三方系统数据,或者自身业务系统需要提供接口给第三方调用,这些都涉及跨域问题。
跨域注意事项
- 服务端设置
Access-Control-Allow-Origin
http头时尽量遵循以下设计原则:
- 权限最小化
CORS规范是全有或全无。它只支持*,null或确切的协议+域+端口
rep.setHeader("Access-Control-Allow-Origin", "*"); // 非必须情况不要这么写
尽量使用白名单,而不是黑名单。
// 允许跨域白名单
const allowDomains = ["http://域名1", "http://域名2", "http://域名3"]
......
注入风险
攻击者通过注入脚本到网站内到达攻击效果。
如前端的xss攻击和后端的sql注入问题。
防御措施
- 不要信任任何外部的输入,要作好转义或者严格的正则过滤。
xss跨站脚本攻击
也属于注入攻击,即黑客注入了html篡改原网页内容。
常见xss类型
反射型
本质就是攻击者通过浏览器一些可操作入口将恶意脚本注入进来并执行.存储型
攻击者将恶意脚本注入到服务器中, 相当于持久化了, 这种危害比较大, 访问到攻击页面的用户都受收到影响.
防御措施:
- 现网上也有挺多方案可提供预防xss攻击的脚本, 另外vue也对模板会进行转义处理.
- 对于外部输入的表单/参数, 做好校验过滤, 转义.
- 不直接执行/展示用户的输入内容, 应该在之前做好过滤
- 为防止攻击者使用脚本利用cookie劫持的方式获取到用户登录凭证, response set-cookie应该设置好httponly属性
csrf跨站请求伪造
跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问另一个恶意页面, 利用浏览器已存在的登录态去做一些操作: 如转账, 发邮件等。
防御措施:
- rerferer check
- token校验
其实我们现在经常看到一些网站设计有以下相关提示:
安全性未知,是否继续
这也是在产品设计角度对csrf漏洞防御手段之一,将用户往更安全的行为上引导,可能会有风险。
前端安全
- vue.config.js {
productionSourceMap
: boolean }
SourceMap即资源地图,默认为true, 开启后能够方便通过控制台打印信息定位到源代码所在文件。
该属性是vue-cli打包提供的配置选项, 若设为false, 打包后代码会经过压缩加密, 不能直接定位到源文件, 相对安全, 且一般打包后的map文件比较大, 从打包优化角度也可选择关闭资源地图。
- 不直接引用外网的cdn资源,下载到本地引入或者上传到公司内网的cdn仓库进行访问。
- 服务端设置HTTP保护头,如nodejs可以使用
helmet
中间件: helmet github地址 -
服务端对每个接口每次访问都要验证好登录态
总结
开发设计在安全角度上要注意的事:
- token/AK/SK等秘钥不要明文写在代码里, 可用环境变量, 系统变量最好加salt处理。
- 注意打印的信息, 敏感信息应该脱敏处理或者加密。
- 不可信任用户/前端的输入, 做好匹配过滤. 尽量用正则, "全等"。
- 敏感的操作前, 应该有安全确认: 审批流, 验证码等。
- 要依赖第三方结果再进行的操作前(如依赖第三方回调接口提供的审批结果去判断是否执行内部的下一步操作), 应该要用 id去源系统进行反查, 确认结果符合预期再操作。
- 用户行为上, 系统中所有用户操作应该都要审计上报到公司监控平台, 记录每个用户在何时做了什么操作(当然也要记录访问的user-agent, ip,url, 请求和返回的参数等, 尽量详细, 方便日后问题定位)。
- 接口访问上, 系统也要记录每个接口的访问成功量, 失败量, 请求耗时, 总请求量等上报到监控平台。
- 提高攻击的门槛,比如验证码,cookie设置时长、readonly参数,token认证等。
- 合理使用验证码, 防止攻击者批量注册, 暴力破解程序。