网站的基本构成
- 前端:JavaScript / vue / react
- 网关:nginx
- 后端:Go / Java / Node
- 前后端交互:HTTP / WebSocket
漏洞分类
服务端漏洞:
SQL注入
外界用户在输入验证的内容中配合SQL语句对数据库进行操作。
以JAVA为例
1、错误使用语言框架、或者语言框架本身存在安全问题
使用Mybatis-plus的危险函数,比如inSql,支持直接SQL拼接,存在SQL注入风险。
- 可以查询其他表中的内容
2、Mybatis使用[$]构建SQL模板
在SQL语句中使用[$]会将参数看作值,其作用和字符串拼接的效果一致,用[#]则将其看作语句,不会存在字符串拼接的漏洞。
3、Golang常见错误写法
SQL注入这一类漏洞会在很多语言以及ORM的框架中出现
举例
db.Order(param).Find(&products)
可以将param替换成if语句,则可以判断SQL注入问题,以及猜测很多其他事情。
防护方法
- 尽量不要基于DB的Raw方法拼接构造SQL语句,而应该使用预编译,ORM框架。
- 使用ORM框架时,应该注意框架中的特性,可能存在不安全的写法导致SQL注入问题。
- 在复杂场景中一定要使用拼接SQL时,需要对外部输入进行转义。
命令执行
代码中遇到需要调用某个命令才能完成的功能时候,会涉及到命令拼接。命令执行漏洞指如果命令拼接没有做好安全过滤,那么将会导致命令注入风险,服务器权限将会被控制。
举例:
如果接口提供库存查询,输入商店id查询库存数量:
productId=1&storeId=1|id
上面的语句通过|符号,在linux中意为管道符,这样可能会修改数据库中信息或者窃取数据库中信息。
防护方法
- 对动态的值尽可能设置白名单进行验证。
- 如果某些位置无法设置白名单,需要尝试对数据类型进行校验。
- 特殊字符黑名单的过滤,或者转义。
越权漏洞
越权:资源访问或操作时主体权限没有进行校验就会造成越权问题,细分为:未授权、水平越权和垂直越权。
水平越权
举例:订单查询功能提供订单id即可查询订单详情,这里攻击者可以便利orderId获取其他用户的订单信息。
防护措施
涉及资源id尽量不要使用短id(遍历难度较小),同时最重要的一定要做好资源属主校验。
垂直越权
举例:攻击者可以通过开通另外的测试管理员账户,或者通过逆向前端代码方式获取实际接口,然后绕过前端直接访问后端接口,获取数据详情。
防护措施
简单场景下可以将接口在路由级别进行分组,对于不同的API分组引入Middleware进行权限拦截,Middleware获取当前角色以确定是否可以访问此接口。
SSRF
服务端请求伪造攻击,将服务器对某些特定内容的链接修改为访问内网页面链接。
防护方式
对url的host进行白名单过滤;获取对host解析的ip进行判定,是否时内网地址。
文件上传漏洞
- 上传文件可以上传解释型语言脚本。
- 免费使用快速的CDN服务
防护方案
- 限制文件类型:如果系统只需要图片类型,可以从服务端解析文件格式,限制只能传入特定的文件格式。
- 站库分离:应用部署的位置和上传的文件分离,一般可以使用TOS、OSS等进行文件存储。
- 防止图床:对图片访问链接进行限制,包括时间限制,访问身份限制。
客户端漏洞:
开放重定向
开放重定向: 某些需要重定向到其他站点的功能,往往在参数中携带需要重定向的URL,但实际程序逻辑没有控制好重定向的范围,导致攻击者可以构造恶意链接,诱导用户重定向到恶意站点。
修复方案:
对重定向严格进行白名单控制并正确校验匹配白名单。
XSS
跨站脚本(XSS)攻击:本质是一种Script代码注入、攻击者目标Web页面里插入恶意Script代码,当用户访问页面(有客户端时需要交互)时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
类似SQL注入,注入Script代码。
场景:反射型,存储型,Domain型
危害:通常的危害包括窃取用户敏感信息,以用户身份执行敏感操作。
防护方法
-
输入过滤:对输入的特殊字符进行拦截,禁止前端提交特殊字符。
-
输出过滤:
- 当字符输出到Domain时,对危险字符进行html encode,避免XSS。
- 使用vue/react等框架时,避免使用危险指令,而应该使用安全指令。v-html/v-text。
-
富文本场景:比如文章发布场景,本身时需要提供富文本功能,这时候需要严格限制tag和attribute,可以在代码层面做白名单或者黑名单。
<tag attribute1='value1' attribute2='value2'/> -
CSP(内容安全策略,Content-Security-Policy),用于缓解XSS,理念时对当前站点允许加载什么源的资源,发送什么请求能进行限制。
Content-Security-Policy: default-src 'self'; img-src *; media-src example.org example.net; script-src userscripts.example.com
CSRF
跨站请求伪造:允许攻击者诱导用户访问恶意链接,执行用户非预期执行的操作。
危害:用户执行敏感操作,如关注其他用户,或者更改账号的安全邮箱等。
漏洞利用步骤:
- 将更改Email的请求生成CSRF表单,并构造钓鱼链接。
- 发送链接给其他用户。
- 用户点击链接后成功执行Email更改操作。
防护方式
防护的核心时判断请求的来源。
- CSRF tokens : 首次访问时给客户端传递一个token,客户端每次访问请求时必须带上此token。
- SameSite cookies : Strick
=》Lax(Default)=》None。核心是禁止某些场景发送第三方cookie。 - Referer-based vaildation:校验Regerer来源是否是合法站点。
点击劫持(clickjacking)
点击劫持(clickjacking)是一种在网页中将恶意代码等隐藏在看似无害或者存在诱导的内容(如按钮)之下,并诱使用户点击的手段,用户点击后往往会执行一些非预期的操作。
防护方式
防护的核心为不让非预期的网站iframe我的站点
-
X-Frame-Options :DENY / SAMEORIGIN
-
CSP : frame-ancestors指令,用于设置允许frame的source列表
Content-Security-Policy: frame-ancestors <space separated list of sources>; Content-Security-Policy: frame-ancestors 'self' https://example.org https://example.com https://store.example.com;
CORS
全称是“跨域资源共享”(Cross-origin resource sharing),用以解决网页应用跨域访问的需求。
常见几种错误配置: |
以需要跨域访问 example.com 所有子域名为例
- 前缀/后缀/包含/正则匹配:可用 example.com.attack.com、attackexample.com、attackaexample.com 域名绕过。
- 反射:在Access-Control-Allow-Origin中反射请求的Origin值。理论上可以用任意域名绕过。
- 信任null:攻击者还可以从任意域下通过iframe sandbox构造Origin为null的跨域请求
- https信任http:http传输存在被劫持篡改可能,攻击者可能通过劫持通信流量注入恶意脚本方式窃取敏感信息。
防护方式:
核心是正确设置跨域白名单代码层:
- Middleware统一处理网关层:
- Nginx反代统一拦截处理。
WebSocket
- WSS 和 WS:WSS (WebSockets over SSL/TLS),提供加密信道。杜绝掉一些中间人攻击。
- 数据校验:SQL/XSS/RCE 等漏洞仍然可能存在。
- CSWSH:Cross-Site WebSocket Hijacking,即在使用cookie作为认证方式时候,如果 WebSocket 服务端没有校验好请求来源(Origin),将导致 WebSocket 会话劫持。
CSWSH 防护手段:
- Cookie鉴权:限制请求的Origin。
- ticket/token鉴权:http服务提供接口,用于获取临时的身份凭证,并传递到WebSocket的初始化流程中。
总结
今天学习了网站的基本构成以及常见的漏洞分类。在服务端漏洞方面,主要涉及到SQL注入、命令执行、越权漏洞、SSRF和文件上传漏洞。对于这些漏洞,我们可以采取相应的防护方法,如使用预编译和ORM框架来防止SQL注入,对动态值进行白名单验证来防止命令执行,对资源访问进行严格的权限校验来防止越权漏洞等。
在客户端漏洞方面,主要介绍了开放重定向、XSS、CSRF、点击劫持和CORS。为了防止开放重定向漏洞,我们需要对重定向进行白名单控制和正确校验匹配;对于XSS漏洞,可以采用输入和输出的过滤、富文本场景的限制以及Content Security Policy(CSP)来防护;对于CSRF漏洞,可以采用CSRF tokens、SameSite cookies和Referer-based validation等方式来进行防护;对于点击劫持,可以通过设置X-Frame-Options和Content Security Policy中的frame-ancestors指令来防止别人通过iframe嵌套攻击;而解决跨域资源共享的问题,可通过正确设置跨域白名单进行防护。
对于WebSocket,需要注意使用WSS进行加密通信,同时仍然需要对数据进行校验,防止SQL注入、XSS和RCE等漏洞。此外,还介绍了CSWSH(Cross-Site WebSocket Hijacking)的防护手段,如限制请求的Origin和使用票据或令牌进行身份验证。
综上所述,网站构成复杂,存在不同类型的漏洞,但我们可以采取相应的防护措施来降低漏洞风险。持续的安全审计和强化措施的落地执行是保障网站安全的重要环节。