什么是漏洞
要解释什么是漏洞,要从网站的基本构成入手。
组成一个网站有以下几个关键要素,攻击者会尝试从这些环节下手攻击:
- 前端:JavaScript / vue / react
- 网关:nginx
- 后端:Go / Java / Node
- 前后端交互:HTTP / WebSocket
常见的安全事件
由安全漏洞引发的攻击事件可能造成一系列恶劣影响,下面几个关键词大家一定不陌生:
- 数据泄露
- 服务瘫痪
- 成果失窃
- 系统劫持
网站攻击者的意图
攻击者可能出于一种或多种意图实施攻击,对攻击者意图的揣测有利于针对性地加强网站安全建设。
- 政治目的:出于政治目的实施黑客攻击。可能涉及窃取关键系统的机密数据、破坏关键系统正常运行。
- 经济目的:网站数据具有很高的经济价值,攻击者通过网站漏洞违法获取数据并进行售卖。
- 竞争目的:同类厂商之间可能由于竞争原因,对竞品网站进行一些攻击,以达到让对方站点无法运行的目的。
- 炫技、泄愤:用攻击对方网站方式彰显自己的技术实力,或者对某些仇恨的系统发起攻击。
红蓝对抗
在网络攻防中有红蓝对抗这个常见的概念。
红军作为企业防守方,通过安全加固、攻击监测、应急处置等手段来保障企业安全。
蓝军作为攻击方,以发现安全漏洞,获取业务权限或数据为目标,利用各种攻击手段,试图绕过红军层层防护,达成既定目标。
实际上一个企业内部可能既有红军,又有蓝军。红军负责系统建设时候帮助企业提前规避漏洞,蓝军负责反向验证企业内部安全现状,以攻促防。
攻击方式
网站攻击可以分为攻击客户端漏洞和攻击服务端漏洞两个方面,以下是一些攻击技术的关键词:
服务端漏洞:
- SQL
- RCE / 命令注入
- SSRF
- 文件上传
- ......
客户端漏洞:
- Xss
- CSRF
- 点击劫持
- ......
下面将会分章节详细介绍各类漏洞
服务端漏洞
第三方组件漏洞
网站开发过程中引用了第三方组件的代码如果存在漏洞,就会波及到我们的服务端。这样的攻击可能发生在有缺陷的发序列化过程中,攻击者会引导服务端下载一段恶意代码再从本地执行。著名的日志库log4j就爆出过这样的漏洞。
针对这种安全问题,可以使用不同语言生态提供的Dependency Check插件来扫描项目使用的依赖,发现潜在的安全问题。这类插件依托漏洞数据库的记录,对比检查出本地所使用的软件版本存在哪些健壮性问题,及时提醒用户更新或降级软件包。
SQL注入漏洞
如果编码过程中存在疏忽,可能造成SQL语句静态模板和动态数据部分没有严格区分。攻击者可以通过在数据项中加入某些SQL语句关键字(比如说OR、UNION、SELECT等等)来改变语句原有的语义,让这些恶意命令在数据库写入或读取数据时得到执行。这可能会造成绕过登录、提权、脱库等严重的安全问题。
很多注入漏洞是因为错误使用了语言的框架,比较少见的是语言框架本身存在安全问题。此类攻击有这些防护方式:
- 尽量不要基于DB的Raw方法拼接构造SOL语句,而应该使用预编译、ORM框架
- 使用ORM框架时,应该注意框架中的特性,可能存在不安全的写法导致的SOL注入问题
- 在复杂场景一定要使用拼接SQL,需要对外部输入进行转义,不要信任用户输入。
命令执行
这个漏洞和SQL注入类似,代码中遇到需要调用某个命令才能完成的功能时候,会涉及到命令拼接,如果命令拼接没有做好安全过滤,那么将会导致命令注入风险,服务器权限将会被控制。比如通过注入Linux管道符的方式,额外执行服务器上的命令收集信息。防护方式:
- 对动态的值尽可能设置白名单进行验证。
- 如果某些位置无法白名单,需要尝试对数据类型进行校验
- 特殊字符黑名单的过滤,或者转义。
越权漏洞
越权漏洞分为未授权、水平越权和垂直越权三类。
未授权
绕过权限得到了需要权限认证才能访问的数据。
水平越权
用户获得相同权限等级的其他用户的权限。
黑灰产场景:订单查询功能提供订单id即可查询订单详情,攻击者可以遍历orderId非法获取其他用户的订单信息
防护方式:
- 涉及资源id尽量不要使用短id (遍历难度较小)
- 一定要做好资源属主校验
垂直越权
低等级用户获得了高等级用户的权限。
黑灰产场景:攻击者可以通过开通另外的测试管理员账户抓包获取接口,或者通过逆向前端代码方式获取实际接口,然后绕过前端直接尝试访问后端接口,获取数据详情。
防护方式:如果是简单的场景,可以将接口在路由级别进行分组,对不同的API分组引入Middleware进行权限拦截,Middleware获取当前用户角色以确定是否可以访问此接口。
SSRF攻击
SSRF又称服务端请求伪造攻击,指攻击者利用后端服务器为跳板,让后端服务向非预期网络地址 (主要指内网地址) 发出恶意请求,获取敏感信息或执行恶意操作。
防护方式:对url的host进行自名单过滤,获取对host解析的ip进行判定,是否是内网地址。
文件上传漏洞
如果上传文件的时候疏于进行文件类型限制和检测,可能会被攻击者上传恶意脚本,然后借助PHP等环境提供的动态能力对服务器造成破坏或泄密。
或者,攻击者可能找到公开的上传点(如视频创作/文章创作/客服反馈 等),上传恶意文件(恶意视频、图片) ,获取图片url,然后直接分享url至外部恶意网站或QQ/微信群。
防护方案
- 限制文件类型:如果系统只需要图片类型,可以从服务端解析文件格式,限制只能传入特定的文件格式。
- 站库分离:应用部署的位置和上传的文件分离,一般可以使用TOS、OSS等进行文件存储
- 防止图床盗链:对图片访问链接进行限制,包括时间限制,访问身份限制等。
客户端漏洞
开放重定向
某些网站为在完成部分操作后,需要重定向到其他站点的功能,往往在参数中携带需要重定向的 URL。但实际程序逻辑没有控制好重定向的范围,导致攻击者可以构造恶意链接,诱导用户重定向到恶意站点,容易造成钓鱼攻击。
修复方案:对重定向严格进行白名单控制并正确校验匹配白名单。
跨站脚本(XSS)攻击
本质是一种脚本代码注入,攻击者往目标网页里插入恶意代码,当用户访问页面时,嵌入其中的代码会被执行从而达到恶意攻击用户的目的。攻击场景分为反射型、存储型、Dom型。
危害:通常的危害包括窃取用户敏感信息,以用户身份执行敏感操作。
防护方法:
- 输入过滤:对输入的特殊字符进行拦截,禁止前端提交特殊字符
- 输出过滤:
- 当字符输出到Dom时候,对危险字符进行html encode,避免XSS。
- 使用vue/react等框架时候,避免使用危险指令,而应该使用安全指令。v-html/v-text
- 富文本场景:比如文章发布场景,本身是需要提供富文本功能,这时候需要严格限制tag和attribute,可以在代码层面做白名单或者黑名单,防止onload,onclick等危险标签的使用
- CSP(Content-Security-Policy):用于缓解XSS,理念是对当前站点允许加载什么源的资源、发送什么请求能进行限制
跨站请求伪造(CSRF)
允许攻击者诱导用户访问恶意链接,执行用户非预期执行的操作。
危害:用户执行敏感操作,如关注其他用户,或者更改账号的安全邮箱等。
防护方式:防护的核心是判断请求的来源
- CSRF tokens:首次访问时候给客户端传递一个token,客户端每次访问时候都必须带上此token才能访问
- SameSite cookies:核心是禁止某些场景发送第三方cookie
- Referer-based validation:校验 Referer 来源是否是合法站点
点击劫持
点击劫持(clickjacking)是一种在网页中将恶意代码等隐藏在看似无害或者存在诱导的内容 (如按钮)之下,并诱使用户点击的手段,用户点击后往往会执行一些非预期的操作。
防护的核心是不让非预期的网站iframe我的站点:
- 设置X-Frame-Options:DENY / SAMEORIGIN
- frame-ancestors指令:用于设置允许frame的source列表
CORS跨域配置错误
CORS全称是“跨域资源共享”(Cross-originresource sharing),用以解决网页应用跨域访问的需求。CORS本身不存在漏洞,而是由于开发者在配置CORS过程中,错误配置跨域访问AIlow List, 导致非预期的站点可以进行跨域访问,最终可能导致信息泄漏。
常见几种错误配置有:(以需要跨域访问 example.com 所有子域名为例)
- 前缀/后缀/包含/正则匹配:可用example.com.attack.com、attackexample.com等域名绕过
- 反射:在Access-Control-Allow-Origin中反射请求的Origin值,理论上可以用任意域名绕过
- 信任null:攻击者可以从任意域下通过iframe sandbox构造Origin为null的跨域请求
- https信任http:http传输存在被劫持篡改可能,攻击者可能通过劫持通信流量注入恶意脚本方式窃取敏感信息
防护方式:核心是正确设置跨域白名单
- 代码层:Middleware统一处理
- 网关层:Nginx反代统一拦截处理
WebSocket问题
本质上http服务端的漏洞,在WebSocket上也可能存在,因此在使用过程中同样有一些注意点:
- 使用WSS (WebSockets over SSL/TLS),提供加密信道。杜绝掉一些中间人攻击
- SQL/XSS/RCE 等漏洞仍然可能存在,因此要注意数据校验
- CSWSH(Cross-Site WebSocket Hijacking):即在使用cookie作为认证方式时候,如果WebSocket服务端没有校验好请求来源(Origin),将导致WebSocket会话劫持。黑产设置钓鱼页面,用户一旦访问后,用户 WebSocket会话就可能会被监听。