网络安全:OWASP防护守则
目录
一、OWASP十大WEB弱点防护守则
二、防护守则
1、权限控制失效
2、加密失误
3、注入
4、不安全设计
5、安全配置缺陷
6、易受攻击和过时的组件
7、身份认证和会话管理失效
8、缺乏完整性校验
9、缺乏监控与日志记录
10、服务端请求伪造
三、核心防护原则总结
一、OWASP十大WEB弱点防护守则
OWASP Top 10 是目前全球最权威、最具影响力的Web应用安全风险清单,由开放Web应用安全项目(OWASP)定期更新(2021版)。
排名 | 风险名称 | 简述 |
---|---|---|
A01 | Broken Access Control | 权限控制失效,导致用户可以访问未授权的数据或功能。 |
A02 | Cryptographic Failures | 加密失误,如未加密敏感数据或使用不安全的算法(旧称“敏感数据泄露”)。 |
A03 | Injection | 注入,包括 SQL、NoSQL、命令注入等,攻击者通过恶意输入操控后端。 |
A04 | Insecure Design | 不安全设计,应用本身的设计缺陷,未考虑安全机制。 |
A05 | Security Misconfiguration | 安全配置缺陷,配置错误或默认设置未更改,导致系统暴露。 |
A06 | Vulnerable and Outdated Components | 易受攻击和过时的组件,使用了已知漏洞的软件组件,如库、框架。 |
A07 | Identification and Authentication Failures | 身份认证和会话管理失效,身份验证机制不当,如弱密码、暴力破解。 |
A08 | Software and Data Integrity Failures | 缺乏完整性校验,例如更新过程未验证签名。 |
A09 | Security Logging and Monitoring Failures | 缺乏监控与日志记录,无法及时响应攻击。 |
A10 | Server-Side Request Forgery (SSRF) | 服务端请求伪造,服务器被诱导请求外部资源,可能造成内网信息泄露。 |
二、防护守则
1、权限控制失效
-
强制实施最小权限原则: 默认拒绝所有访问,明确授予每个用户/角色执行其任务所需的最小权限。
-
集中化访问控制检查: 在服务器端使用统一的、经过严格测试的授权机制(如RBAC, ABAC),避免在客户端进行关键权限判断。
-
禁用目录列表: 确保Web服务器不会列出目录内容。
-
记录和监控访问失败: 记录失败的授权尝试并设置告警(尤其是管理员操作)。
-
API速率限制: 防止暴力破解和数据枚举。
-
强制所有权检查: 对访问对象(如文件、数据库记录)的操作前,必须验证当前用户是否拥有该对象(
/users/{id}
中验证{id}
属于当前用户)。 -
唯一、不可预测的访问令牌: 使用JWT时设置短有效期,注销时使其失效。
2、加密失误
-
敏感数据加密: 对传输中的敏感数据(密码、个人信息、支付信息、健康数据等)强制使用强TLS(最新版如TLS 1.3),对存储的敏感数据使用强加密算法(如AES-256)和安全的密钥管理(HSM/KMS)。
-
禁用旧协议/弱算法: 禁用SSL、早期TLS版本、弱密码套件(如RC4, DES, MD5, SHA1)。
-
使用强哈希存储密码: 使用自适应哈希算法(如Argon2id, scrypt, bcrypt, PBKDF2)并加盐。
-
禁止缓存敏感数据: 在HTTP响应头设置
Cache-Control: no-store
。 -
最小化数据收集和存储: 只收集和存储业务绝对必需的敏感数据,及时删除不再需要的数据。
-
避免在代码/配置中硬编码密钥: 使用安全的密钥管理系统。
3、注入
-
使用安全的API: 优先使用提供自动参数化或安全对象关系映射(ORM)的API。绝对禁止拼接查询/命令。
-
参数化化查询: 对SQL、NoSQL、OS命令、LDAP查询等所有解释型语句,使用参数化查询(预编译语句)或存储过程。
-
输入验证与输出编码: 对不受信任的输入进行严格的、基于白名单的验证(类型、长度、格式、范围)。在将数据输出到不同上下文(HTML, JavaScript, CSS, URL, SQL)时,使用上下文相关的输出编码。
-
使用ORM框架的安全方法: 避免使用可能引入注入的拼接方法。
-
LIMIT 防止大规模数据泄露: 在SQL查询中使用LIMIT等子句限制返回行数。
4、不安全设计
-
威胁建模: 在设计和开发生命周期早期(SDLC)进行威胁建模,识别潜在威胁并设计安全控制措施。
-
安全设计模式: 采用成熟的安全设计模式和原则(如深度防御、最小权限、失效安全)。
-
安全需求定义: 明确定义安全需求(如认证、授权、审计、加密、输入验证)。
-
参考架构和安全控制库: 使用经过验证的安全参考架构和可重用的安全组件。
-
安全编码标准与培训: 制定并强制执行安全编码标准,对开发人员进行安全培训。
-
滥用案例建模: 考虑攻击者可能如何滥用应用功能,并设计相应的防护。
5、安全配置缺陷
-
最小化安装: 移除不必要的功能、组件、文档、示例和未使用的账户。
-
加固配置: 为操作系统、框架、库、应用程序设置安全、强化的配置(关闭调试模式、禁用管理接口、设置安全HTTP头如CSP, HSTS, X-Content-Type-Options等)。
-
自动化配置管理: 使用自动化工具(IaC如Terraform, Ansible)确保开发、测试、生产环境配置一致且安全。避免使用默认凭据。
-
及时更新和打补丁: 建立流程,及时更新和修补操作系统、框架、依赖库和应用程序。
-
分离组件: 将不同安全级别的组件部署在隔离的网络分段或容器中。
-
安全扫描: 定期进行配置审计和安全扫描。
6、易受攻击和过时的组件
-
组件清单管理: 维护所有客户端和服务器端组件(框架、库、模块)及其版本的准确清单(使用SCA工具)。
-
持续监控漏洞: 订阅安全通告(CVE),使用软件成分分析(SCA)工具持续监控组件漏洞。
-
及时更新/打补丁: 仅从官方渠道获取组件,在评估风险后及时应用安全补丁或升级到安全版本。优先考虑有活跃维护的组件。
-
移除无用/过时组件: 清理不再使用的依赖项。
-
安全许可: 在引入新组件前进行安全评估和许可。
7、身份认证和会话管理失效
-
实施强认证: 支持多因素认证(MFA),尤其是关键操作和高权限账户。防止弱密码(使用密码策略、密码强度检查器、阻止常见密码)。
-
安全的会话管理: 使用服务器端生成的、长且随机的会话ID,通过安全Cookie传输(
Secure
,HttpOnly
,SameSite
属性),设置合理的会话超时(空闲和绝对超时)。 -
安全的密码管理: 使用强哈希存储密码(见A02),安全地处理密码重置/忘记流程(避免知识问答、发送明文密码),提供安全的密码更改功能。
-
防止凭证填充/暴力破解: 实施账户锁定或递增延迟机制,记录失败尝试并监控。对登录尝试进行速率限制。
-
统一错误消息: 登录、注册、密码找回等环节使用统一的模糊错误消息(如“用户名或密码错误”),避免枚举攻击。
8、缺乏完整性校验
-
代码/配置完整性验证: 使用数字签名验证软件来源和完整性(如代码签名、容器镜像签名)。确保CI/CD管道安全,防止未授权修改。
-
依赖来源可信: 只从官方、受信任的源获取依赖项和插件。验证其签名或哈希值。
-
反序列化安全: 避免使用包含远程代码执行功能的危险反序列化器。如必须使用,实施严格的输入验证、类型限制(白名单)和沙箱隔离。
-
CI/CD安全: 保护构建管道,确保代码仓库、构建服务器的访问控制和安全配置。
-
关键数据完整性保护: 对关键配置或数据使用数字签名或MAC(消息认证码)验证其未被篡改。
9、缺乏监控与日志记录
-
记录关键安全事件: 确保记录登录(成功/失败)、访问控制失败、输入验证失败、系统错误、关键操作(如密码修改、权限变更)、API调用等。
-
日志包含足够上下文: 日志条目应包含时间戳、源IP、用户标识、事件描述、操作结果等,便于调查。
-
集中化日志管理: 将日志发送到受保护的、集中的日志管理系统(如SIEM),防止本地篡改或丢失。
-
实时监控与告警: 建立实时监控机制,对可疑活动(如大量登录失败、异常数据访问模式)设置告警阈值,确保告警能被及时响应。
-
定期审计与测试: 定期审计日志配置和内容,进行渗透测试验证监控的有效性。
-
保护日志数据: 确保日志存储的安全性和完整性,控制对日志的访问权限。
10、服务端请求伪造
-
输入验证与过滤: 对用户提供的URL或主机名/IP进行严格的基于白名单的验证和过滤。避免直接使用用户输入构造请求。
-
网络层控制: 实施网络分段,将后端应用部署在隔离网络(DMZ),限制其只能访问必要的内部资源。使用防火墙策略限制应用服务器出站连接的目标地址和端口。
-
应用层控制: 使用应用层代理或具有严格目标限制的API网关来转发请求。
-
禁用非必要URL Schema: 仅允许
http
/https
,禁用file
,ftp
,gopher
,dict
等危险schema。 -
验证响应: 不要将原始响应直接返回给客户端,检查响应内容是否合法。
-
使用受信解析库: 避免直接使用底层网络库处理用户输入。
三、核心防护原则总结
-
纵深防御: 在多个层面实施安全控制。
-
最小权限: 只授予完成任务所必需的最小权限。
-
默认安全: 默认配置应是最安全的。
-
永不信任用户输入: 对所有输入进行严格验证、过滤和输出编码。
-
保持简单: 减少攻击面(移除不必要的功能、组件)。
-
持续更新: 及时打补丁和升级。
-
安全开发生命周期: 将安全融入设计、开发、测试、部署、运维全过程(DevSecOps)。
-
监控与响应: 具备检测、响应和恢复能力。