安全
一、服务器安全漏洞
说白了,核心防护措施是,针对所有不可控的地方(用户可以输入的地方),做好严格的控制检查。
1.1 第三方组件漏洞
尽量不要用不安全的版本,适当更新版本。
1.2 SQL注入
1.2.1 正确使用 ORM 框架
- 使用安全的 ORM 框架,如 MyBatis 和 GROM。
- 要注意正确安全的用法,例如在 MyBatis 中采用
#
作为占位符。
1.2.2 使用参数绑定
-
参数绑定是防止 SQL 注入的最佳实践,因为它会自动转义特殊字符,将用户输入当作数据处理,而不是 SQL 代码。
-
在不同的编程语言和数据库驱动中,参数绑定方法有所不同。例如,在 Java 中使用
PreparedStatement
,在 Python 中使用cursor.execute
,并传入参数。 -
示例 (Java):
String sql = "SELECT * FROM users WHERE name = ?"; PreparedStatement stmt = connection.prepareStatement(sql); stmt.setString(1, userInput);
这里的
?
占位符会自动绑定userInput
的内容,并自动进行必要的转义处理。
1.2.3 单引号的转义
-
在 SQL 中,单引号 (
'
) 用于字符串的开始和结束。如果字符串中包含单引号,需要使用两个单引号 (''
) 进行转义,以避免 SQL 注入。 -
示例:
SELECT * FROM users WHERE name = 'O''Reilly';
这里,
O'Reilly
中的单引号被转义为两个单引号,防止语句结构被破坏。
1.2.4 使用数据库内置的转义函数
-
有些数据库提供转义函数来处理特殊字符。不同数据库的函数名称和用法有所不同,例如:
-
MySQL:
QUOTE
函数SELECT * FROM users WHERE name = QUOTE('O'Reilly');
-
PostgreSQL:
quote_literal
函数SELECT * FROM users WHERE name = quote_literal('O'Reilly');
-
-
这些函数会自动将输入字符串中的特殊字符进行转义。
1.3 转义补充
当然,转义不仅用于 SQL,还有很多其他场景需要转义。以下是一些常见的转义示例:
1.3.1 HTML 转义
-
在 HTML 中,某些字符具有特殊含义,比如
<
,>
,&
, 和"
等。如果用户输入的文本直接插入到 HTML 中,可能会破坏页面结构或引发 XSS(跨站脚本攻击)。 -
例子:
<
转义为<
>
转义为>
&
转义为&
"
转义为"
-
示例代码:
<p>User input: <script>alert('XSS')</script></p>
1.3.2 URL 转义(URL 编码)
-
在 URL 中,某些字符需要编码,例如空格、
?
,&
,=
等字符。如果直接在 URL 中使用这些字符,可能会导致 URL 被误解。 -
例子:
- 空格转义为
%20
?
转义为%3F
&
转义为%26
- 空格转义为
-
示例代码:
https://example.com/search?query=hello%20world
1.3.3 JSON 转义
-
在 JSON 中,字符串值中的特殊字符需要转义,特别是双引号和反斜杠。
-
例子:
"
转义为\"
\
转义为\\
- 回车
\n
,制表符\t
-
示例代码:
{ "message": "He said, \"Hello, World!\"" }
1.3.4 正则表达式转义
-
在正则表达式中,许多字符具有特殊含义(如
*
,+
,?
,[
,]
,(
,)
,|
,.
等),在需要匹配这些字符本身时要进行转义。 -
例子:
.
转义为\.
(表示匹配一个点字符,而不是任意字符)*
转义为\*
(表示匹配星号本身)
-
示例代码:
\d+\.pdf // 匹配数字后跟 .pdf 的文件名,比如 "123.pdf"
1.3.5 Shell 转义
-
在 Shell 命令中,某些字符如空格、引号、
&
,|
,;
等具有特殊含义,直接使用时会改变命令的行为,需要转义来避免意外执行命令。 -
例子:
&
转义为\&
|
转义为\|
- 引号内的内容通常会被视为单个字符串
-
示例代码:
echo "This is a safe way to include symbols like & and | in a command"
1.3.6 XML 转义
-
在 XML 中,类似 HTML 的转义规则用于特殊字符,如
<
,>
,&
,"
和'
。 -
例子:
<
转义为<
>
转义为>
&
转义为&
-
示例代码:
<message>Welcome <user>!</message>
1.3.7 CSV 转义
- 在 CSV 中,逗号和换行符可能需要特殊处理。例如,用双引号包裹含有逗号的字段。
- 例子:
"John, Doe"
表示姓名字段包含逗号- 换行符等也需要适当处理
1.3.8 总结
- 转义是为了让特殊字符在不同场景中失去它们的特殊含义,以避免意外行为或安全问题。不同的场景(SQL、HTML、URL、JSON 等)有各自的转义规则,需要根据具体情况来使用。
- 在我们不可控的地方(用户输入)要进行严格的检查评审,适当进行转义。
1.4 命令执行
- 跟SQL注入很类似,不细讲了。
- 对动态的值尽可能设置白名单进行验证。
- 如果某些位置无法白名单,需要尝试对数据类型进行校验。
- 特殊字符黑名单的过滤,或者转义。
1.5 越权漏洞
一种可行措施是 token + RBAC,每次请求都检查用户和角色,避免水平越权和垂直越权,具体细节如下:
使用 Token 进行前端和后端的通信确实是一个有效的安全方案,每次请求都必须携带 Token,并在后端验证 Token 中的角色和用户信息,以防止水平越权和垂直越权。下面是具体的实现和防护策略:
1.5.1 Token 中的信息签名与加密
- 签名:使用签名(如 JWT 中的 HMAC 或 RSA 签名)确保 Token 未被篡改。解码 Token 时验证签名,确保 Token 内容的完整性。
- 加密:对于敏感信息(如角色权限、用户信息),可以选择性加密 Token 内容或将敏感信息以密文的形式存储,避免被截获后破解。
1.5.2 Token 的定期刷新和过期控制
- Token 过期:Token 设置合理的过期时间(如 30 分钟),定期刷新(如用户活动时延长 Token 有效期),避免长期使用同一个 Token,增加安全性。
- Token 黑名单机制:实现 Token 黑名单,在用户登出、账户锁定或权限变更时,将旧 Token 作废,防止未授权用户利用过期 Token。
1.5.3 避免客户端存储 Token 暴露
- 安全存储:避免将 Token 存在
localStorage
或sessionStorage
中,这些存储方式容易受 XSS 攻击。更安全的方法是将 Token 存储在 HTTP-only Cookie 中,前端无法直接访问。 - 请求头传输:每次请求时通过
Authorization
请求头传输 Token,减少 Token 曝露风险。
1.6 SSRF 攻击
- SSRF(Server-Side Request Forgery),即服务器端请求伪造,是一种网络安全漏洞,攻击者通过漏洞诱导服务器发送伪造请求,访问或操作原本不允许访问的内部资源(如内网 IP、敏感服务等)。这种攻击通常利用了服务器的信任关系来窃取敏感信息或在内部系统中发起恶意操作。
- 防御措施可以包括:
- URL 白名单:限制 URL 必须是公司或可信第三方的域名。
- 防火墙限制:限制服务器只能访问必要的公网 IP 或指定的 URL。
- 格式验证:对用户输入的 URL 进行正则表达式验证,禁止使用 IP 地址或敏感域。
1.7 文件上传
防护方案:
- 限制文件类型:如果系统只需要图片类型,可以从服务端解析文件格式,限制只能传入特定的文件格式。
- 站库分离:应用部署的位置和上传的文件分离,一般可以使用TOS、OSS等进行文件存储。
- 防止服务器被当成免费图床:对图片访问链接进行限制,包括时间限制,访问身份限制等。
1.8 DDos 攻击
- **DDoS(Distributed Denial of Service,分布式拒绝服务攻击)**是一种通过大量恶意流量淹没目标服务器、网络或应用程序的攻击方式。攻击者通过分布式网络(通常是由受控的僵尸网络或肉鸡组成)发起大规模请求,导致目标系统资源耗尽,无法为正常用户提供服务。
- DDoS 攻击可以分为以下几类:
1.8.1 流量型攻击(Volumetric Attacks)
- 这种攻击通过大量的虚假流量淹没网络带宽,使得正常流量无法到达目标服务器。
- 常见方式:
- UDP Flood:攻击者发送大量的 UDP 数据包,耗尽目标带宽。
- ICMP Flood(Ping Flood):攻击者发送大量的 ICMP 数据包,占用带宽。
- 特点:主要消耗带宽资源,通常攻击流量可以达到数十 Gbps 甚至 Tbps。
1.8.2 协议型攻击(Protocol Attacks)
- 这种攻击通过滥用网络协议的漏洞或设计缺陷,消耗服务器或中间网络设备(如防火墙、负载均衡器)的资源。
- 常见方式:
- SYN Flood:攻击者发送大量 SYN 包,但不完成 TCP 三次握手,导致服务器维持大量半连接状态,占用连接资源。
- ACK Flood:发送大量 ACK 包,耗尽服务器的处理能力。
- Ping of Death:发送超大 ICMP 数据包,导致目标系统崩溃。
- 特点:主要消耗网络设备和服务器的连接表或状态资源。
1.8.3 应用层攻击(Application Layer Attacks)
- 这种攻击针对应用程序本身,发送大量合法的请求,导致应用服务器资源耗尽(如 CPU、内存)。
- 常见方式:
- HTTP Flood:发送大量 HTTP 请求,模拟真实用户访问,使服务器无法应对正常用户请求。
- Slowloris:攻击者发送不完整的 HTTP 请求,使服务器保持连接并等待数据,从而消耗连接资源。
- DNS Flood:向 DNS 服务器发送大量请求,消耗 DNS 解析资源。
- 特点:通常攻击流量较小,但请求频率高、资源消耗大。
1.8.4 网络层防护
- 流量清洗:利用专用的 DDoS 防护服务(如 Cloudflare、Akamai、AWS Shield 等),将流量引导到清洗中心,过滤恶意流量后将正常流量发送到服务器。
- 防火墙和入侵防御系统(IPS):配置防火墙和 IPS,拦截常见的攻击模式,如 SYN Flood、ICMP Flood 等。
- 负载均衡:通过负载均衡器将流量分配到多个服务器,减轻单个服务器的压力,并提高系统的抗压能力。
1.8.5 协议层防护
- 限制连接数:对单个 IP 的连接数和连接速率进行限制,防止恶意 IP 发起大量连接。
- SYN Cookie:防止 SYN Flood 攻击的一种技术,在 TCP 握手过程中使用 cookie 验证以节省资源。
- 限速和黑名单:设置网络速率限制,对异常请求的 IP 添加到黑名单,避免协议滥用攻击。
1.8.6 应用层防护
- 使用 Web 应用防火墙(WAF):WAF 可以检测和阻止 HTTP Flood 等应用层攻击,并提供规则来限制请求频率。
- CAPTCHA 验证:通过验证码区分真实用户和自动化攻击请求,防止 HTTP Flood、Slowloris 等攻击。
- 限流和速率限制:针对应用程序接口(API)或特定路径设置请求速率限制,防止恶意请求大量访问。
1.8.7 分布式部署和 CDN
- CDN(内容分发网络):通过 CDN 缓存静态资源,将请求分散到全球各地的 CDN 节点上,减少对源站的压力。
- 多数据中心架构:将服务部署到多个地理位置的数据中心,降低单一数据中心被攻击的风险。
1.8.8 监控和报警机制
- 实时监控:监控流量模式,设置报警阈值,及时发现异常流量。
- 日志分析:分析服务器日志,发现攻击特征并及时调整防护策略。
- 定期演练:定期进行 DDoS 攻击模拟演练,确保防护措施有效,团队具备应对能力。
1.8.9 总结
DDoS 攻击通过大量分布式请求消耗目标资源,导致服务中断。防御 DDoS 攻击需要多层次的防护措施,包括流量清洗、协议防护、应用层防护、CDN 加速、限流和监控等。通过建立全面的防护体系,可以最大程度地减少 DDoS 攻击的影响。