OWASP Top 10 攻击场景实战
OWASP (开放式Web应用程序安全项目) Top 10 榜单是全球公认的、针对Web应用最关键安全风险的权威指南。它不是一份详尽无遗的清单,而是一份凝聚了安全专家共识的“高危预警”。
本文将不止于罗列这些风险,而是深入每个风险的核心,通过生动的比喻、真实的攻击场景和攻击者视角,帮助开发者、测试人员和运维工程师理解漏洞的本质。最重要的是,我们为每一项风险都提供了具体的防御和缓解措施,助您构建更坚固的数字堡垒。
A01:2021 - 访问控制失效
核心问题
“系统没分清你是谁,就让你做了不该做的事。”
风险解读
访问控制旨在强制执行策略,使用户无法在其预期权限之外执行操作。访问控制失效就是指这些限制没有得到正确实施。攻击者可以利用这些缺陷,访问未经授权的功能或数据,例如访问其他用户的帐户、查看敏感文件、修改其他用户的数据、更改访问权限等。
常见利用场景
ID遍历与数据爬取 (IDOR): 攻击者编写脚本循环请求 /api/orders/1001, /1002...,如果系统没有验证ID归属,就能轻松爬取所有用户的数据。
权限提升: 普通用户尝试直接访问管理员URL如 /admin/dashboard,如果后端接口没检查角色,瞬间“变身”为管理员。
越权修改/删除: 攻击者抓取修改自己公司信息的API请求,把其中的公司ID改成竞争对手的,从而篡改对手数据。
CORS配置错误: 错误的CORS策略允许恶意网站读取私有API的响应,绕过了同源策略。
防御与缓解措施
默认拒绝原则: 除了公共资源外,默认情况下应拒绝所有访问,然后根据角色和权限逐一授权。
强制执行权限检查: 在每个服务端功能点,都必须基于用户的会话和角色,强制执行访问控制检查,切勿信任来自客户端的任何权限声明。
数据归属权验证: 在操作任何数据记录时(如查看、修改、删除),必须验证当前用户是否是该记录的所有者。
集中化访问控制逻辑: 将访问控制逻辑统一管理,避免在代码各处分散实现,便于审计和维护。
关闭目录列表: 防止攻击者直接浏览服务器上的文件目录。
攻击者视角
“你前门关得再好,只要后门(API)不认人,我就能直接进去拿东西。”
A02:2021 - 加密机制失效
核心问题
“你的秘密写在了明信片上,而不是锁在保险箱里。”
风险解读
此风险涵盖了与加密技术相关的所有失败,无论是传输中的数据(in-transit)还是静态数据(at-rest)。这可能包括使用弱加密算法、未加密敏感数据、错误的密钥管理或使用过时的协议。根本原因通常是对敏感数据的保护不足。
常见利用场景
拖库与撞库: 拖库后发现密码是明文或MD5/SHA1等弱哈希,立即获得真实密码,然后用这些密码去尝试登录其他高价值网站(撞库)。
中间人攻击: 在公共Wi-Fi下,如果网站登录页或API是HTTP,攻击者可直接监听并窃取账号密码、Cookie等敏感信息。
硬编码密钥: 通过反编译App或分析JS文件,找到硬编码的API密钥、加密密钥,从而伪造请求或解密本地存储的敏感数据。
URL参数泄露: 将Session ID、API Key等敏感信息直接放在URL中,容易被浏览器历史、网络日志、Referer头记录和泄露。
防御与缓解措施
全站强制HTTPS: 使用TLS(最新版本)加密所有传输中的数据,并配置HSTS(HTTP严格传输安全)头,强制浏览器使用HTTPS。
强哈希算法存储密码: 使用Bcrypt、Scrypt或Argon2等现代的、加盐的、慢速的哈希算法来存储密码和凭证。
按需加密静态数据: 识别应用处理的所有敏感数据(如PII、支付信息),并对它们进行加密存储。
安全的密钥管理: 切勿硬编码密钥。使用安全的密钥管理系统(如AWS KMS, HashiCorp Vault)来存储和轮换密钥。
禁用弱算法和协议: 在服务器配置中明确禁用过时的SSL/TLS版本和弱加密套件。
攻击者视角
“拿到你的数据只是第一步,能读懂它才是胜利。谢谢你没给我增加难度。”
A03:2021 - 注入
核心问题
“你本想让我查个名字,我却让你执行了我的命令。”
风险解读
注入漏洞允许攻击者将恶意数据作为命令或查询的一部分发送到解释器。当应用程序将不受信任的输入与命令或查询拼接在一起时,就会发生这种情况。攻击者的恶意数据可以欺骗解释器,执行非预期的命令或访问未经授权的数据。最常见的包括SQL注入、NoSQL注入、OS命令注入、LDAP注入等。
常见利用场景
SQL注入登录绕过: 在用户名输入 ' OR '1'='1' --,让SQL查询永远为真,无需密码直接登录管理员账户。
SQL注入数据窃取: 通过构造复杂的UNION SELECT语句,让搜索结果附带返回数据库中其他表的敏感数据,如用户表。
命令注入获取Shell: 在Ping或文件转换等功能中输入 8.8.8.8; nc -lvp 4444 -e /bin/bash,让服务器执行反向连接命令,从而远程控制服务器。
跨站脚本(XSS): 注入<script>alert('xss')</script>到评论区,导致其他用户访问页面时执行恶意脚本。虽然XSS在2021版中被归类到注入,但其影响和防御方式通常被独立讨论。
防御与缓解措施
使用安全的API: 首选使用提供参数化接口的API,如预编译语句(Prepared Statements)或参数化查询(Parameterized Queries)。这是防御SQL注入最有效的方法。
服务端输入验证: 对所有输入数据进行验证,实施白名单策略,只接受已知的、合法的字符和格式。
上下文输出编码/转义: 当必须将用户输入插入到HTML、SQL、OS命令中时,根据其上下文进行严格的编码或转义。
最小权限原则: 确保数据库用户只拥有其完成任务所必需的最小权限,避免使用root或sa账户。
攻击者视角
“你程序的每个输入框,对我来说都是一个可能的话筒,可以让我直接对你的后端发号施令。”
A04:2021 - 不安全设计
核心问题
“你的代码写得没错,但你的逻辑本身就是个笑话。”
风险解读
这是一个关注“设计缺陷”而非“实现错误”的类别。它强调安全需要从一开始就融入到软件开发生命周期中(“安全左移”)。不安全的设计无法通过完美的实现来修复,它要求在设计阶段就进行威胁建模,识别并规避业务逻辑上的漏洞。
常见利用场景
业务逻辑漏洞套利: 利用可无限次使用的优惠券、无上限的推荐奖励,或商品加入购物车后价格锁定等逻辑,编写脚本自动化“薅羊毛”。
密码重置逻辑缺陷: 利用“忘记密码”功能对任意用户进行短信轰炸;或利用永不失效、可预测的重置链接反复修改他人密码。
无限次尝试: 对没有尝试次数限制的登录接口、兑换码接口、支付接口进行“暴力破解”,直到成功。
缺乏流程顺序校验: 允许用户跳过支付步骤直接访问购买成功页面,或跳过验证步骤直接修改个人资料。
防御与缓解措施
进行威胁建模: 在设计阶段,分析系统的资产、威胁、入口点和潜在攻击场景,并设计相应的控制措施。
使用安全设计模式: 采用经过验证的安全设计模式来构建访问控制、身份验证、工作流等关键模块。
限制业务逻辑流: 对关键业务流程(如注册、购买、重置密码)实施严格的速率限制、顺序校验和资源消耗限制。
分离信任边界: 明确系统内外的信任边界,并对跨越边界的数据和调用进行严格审查。
攻击者视角
“我不需要攻击你的代码,我只需要利用你规则里的漏洞,就能让你按我的剧本走。”
A05:2021 - 安全配置错误
核心问题
“你的房子盖得很结实,但你忘了锁门,还把调试后台的地址贴在了门上。”
风险解读
安全配置错误是目前最常见的安全问题。它源于不安全的默认配置、不完整的临时配置、开放的云存储、错误的HTTP头配置,以及包含敏感信息的详细错误信息。这不仅限于应用服务器,还包括平台、Web服务器、数据库、框架和任何其他软件组件。
常见利用场景
默认口令入侵: 使用自动化工具扫描互联网,用广为人知的默认密码(如admin/admin, root/password)尝试登录数据库、管理后台、路由器等。
暴露的云存储: 通过搜索引擎或专用工具发现配置为“公共读取/写入”的AWS S3存储桶或Azure Blob,直接下载或上传所有公司文档和用户数据。
泄露信息的错误页面: 故意触发程序错误,从返回的详细堆栈跟踪(Stack Trace)页面中获取服务器的操作系统、框架版本、内部文件路径等详细“地图”。
未移除的调试功能: 生产环境中遗留了/debug、/status等调试页面,暴露了系统内部状态。
防御与缓解措施
建立安全基线: 为所有部署环境(开发、测试、生产)建立可重复、自动化的安全强化流程,确保配置一致。
最小化平台: 移除或不安装不必要的功能、组件、文档和示例应用。
审查和加固配置: 定期审查云服务、服务器、框架和库的配置,禁用不安全的默认设置,并应用最新的安全最佳实践。
自定义错误页面: 配置Web服务器和应用框架,以显示统一的、不包含敏感信息的错误页面。
自动化扫描: 使用自动化工具定期扫描系统,检查是否存在配置错误。
攻击者视角
“我最喜欢的就是懒惰的管理员。他们留下的默认设置,就是给我留的后门。”
A06:2021 - 使用含已知漏洞的组件
核心问题
“你信任了你的队友(第三方库),但你的队友却是个身中剧毒的‘内鬼’。”
风险解读
现代应用严重依赖各种开源或商业的第三方组件、库和框架。如果这些组件存在已知的安全漏洞,而你的应用又恰好使用了它们,那么你的应用就继承了这些风险。攻击者会主动扫描使用这些脆弱组件的系统,并发动已知的攻击。
常见利用场景
大规模自动化利用(如Log4Shell): 向所有网站的请求头中插入恶意JNDI查找字符串,一旦服务器使用了有漏洞的Log4j版本,攻击者就能立即获得其控制权。
利用过时框架漏洞: 专门寻找仍在使用老旧版本Apache Struts2、Fastjson、ThinkPHP的网站,用网上公开的漏洞利用工具(PoC/Exploit)进行一键式攻击。
前端库漏洞(XSS): 构造恶意URL,利用网站使用的旧版jQuery或AngularJS插件中的DOM-XSS漏洞,在受害者浏览器上执行脚本,窃取Cookie。
防御与缓解措施
建立软件物料清单(SBOM): 清楚地知道你的应用使用了哪些组件,包括它们的版本和依赖关系。
定期漏洞扫描: 使用软件成分分析(SCA)工具(如OWASP Dependency-Check, Snyk, Dependabot)自动扫描项目中的组件,及时发现已知漏洞。
及时更新和打补丁: 建立一个流程,用于监控安全公告,并在厂商发布安全补丁后,尽快测试和应用更新。
移除未使用组件: 定期清理项目中不再使用的依赖项、文件和功能,减少攻击面。
虚拟补丁: 如果无法立即升级组件,可以考虑使用Web应用防火墙(WAF)等工具创建规则,临时阻止对已知漏洞的利用。
攻击者视角
“我不需要成为第一个发现漏洞的人,我只需要比你更勤快地关注安全新闻,然后利用你没来得及修复的漏洞就行了。”
A07:2021 - 身份识别和身份验证失败
核心问题
“证明‘你是你’的过程太草率了。”
风险解读
当与用户身份验证和会话管理相关的功能没有被正确实现时,就会出现此问题。这可能允许攻击者窃取密码、密钥或会话令牌,或者利用其他实现缺陷来冒充其他用户的身份。
常见利用场景
会话固定(Session Fixation): 攻击者将自己的会话ID通过链接发给受害者,受害者用这个ID登录后,攻击者手里的旧会话ID就“升级”为已登录的会话。
JWT令牌配置不当: 使用算法为none的JWT,或使用永不失效、超长有效期的令牌,导致在用户修改密码甚至禁用账户后,旧令牌依然可以访问系统。
弱密码策略和暴力破解: 用一个包含Top 10000弱密码的字典对允许设置弱密码(如“123456”)的网站进行自动化尝试,轻松破解大量账户。
凭证填充(Credential Stuffing): 利用从其他网站泄露的用户名密码对,批量尝试登录你的网站,成功率很高。
防御与缓解措施
强制多因素身份验证(MFA): 为所有用户,特别是高权限用户,提供并强制启用MFA。
实施强密码策略: 要求密码满足一定的长度和复杂度,并使用密码强度计进行检查。禁止使用常见弱密码。
防范暴力破解和凭证填充: 对登录、密码重置等关键操作实施速率限制和账户锁定策略。
安全的会话管理: 用户登录后立即生成新的、高随机性的会话ID。使用安全的Cookie属性(Secure, HttpOnly, SameSite=Strict)。为会话设置合理的超时时间。
安全的密码恢复机制: 确保密码重置链接是单次有效、有时效性且不可预测的。
攻击者视角
“只要你的‘门票’(会话ID)容易伪造或窃取,或者你的‘密码锁’一猜就开,我就能大摇大摆地冒充任何人。”
A08:2021 - 软件和数据完整性故障
核心问题
“你收到的东西在半路上被掉了包,而你却毫不怀疑地接受了它。”
风险解读
这类故障涉及代码和基础设施,但未能防止完整性违规。一个典型的例子是,应用程序依赖于来自不受信任来源、存储库和内容分发网络(CDN)的插件、库或模块。不安全的反序列化也属于此类,它指的是应用程序在没有验证其完整性的情况下,接受并处理了可能被篡改的序列化对象。
常见利用场景
不安全的反序列化: 应用程序接收一个序列化的Java对象,攻击者构造一段包含“执行系统命令”的恶意序列化数据(称为“gadget chain”),当服务器反序列化时触发该指令,导致远程代码执行(RCE)。
供应链攻击: 入侵流行的NPM包或Python库的维护者账户,在代码中植入恶意后门并发布新版本。所有配置了自动更新的项目在构建时都会被感染。
未验证的软件更新: 应用程序的自动更新功能从一个HTTP URL下载更新包,攻击者通过中间人攻击,将合法的更新包替换成植入后门的恶意包,在设备更新时获得其控制权。
防御与缓解措施
验证软件完整性: 在从任何来源(包括官方仓库)获取依赖库、框架或软件时,都应使用其数字签名或哈希值进行完整性校验。
保护CI/CD管道: 确保你的构建和部署流程是安全的,防止未经授权的代码修改被注入到最终产品中。
避免不安全的反序列化: 尽可能避免使用需要反序列化的数据格式。如果必须使用,应实施严格的类型约束,并对反序列化过程进行完整性检查,或使用数字签名保护序列化对象的完整性。
使用可信赖的软件源: 配置包管理器只从已知的、可信的内部或官方仓库下载组件。
攻击者视角
“攻击你的服务器太难了,不如直接攻击你信任的、防备更松懈的‘供应商’(第三方库)。”
A09:2021 - 安全日志和监控失败
核心问题
“我进来偷东西、踩点、甚至放了火,但你的监控是坏的,所以你一无所知。”
风险解读
缺乏充分的日志记录、监控和有效的告警机制,会严重阻碍对安全事件的检测、响应和取证。没有日志,攻击活动可能无法被发现;即使发现了,也无法确定攻击的范围、路径和根本原因,使得修复和追责变得异常困难。
常见利用场景
长时间潜伏(APT): 由于缺乏对异常行为的监控,攻击者可以花几个月时间在系统内悄无声息地进行侦察、横向移动和权限提升,最后才窃取数据或造成破坏。
暴力破解不被发现: 脚本对登录接口进行高频密码尝试,但因系统没有对大量的登录失败事件进行记录和告警,导致攻击持续进行,无人干预。
无法溯源: 数据泄露事件发生后,由于日志记录不充分(例如,没有记录源IP、操作细节),导致无法调查攻击者的入口点、操作路径,也无法准确评估损失和弥补漏洞。
告警风暴: 日志系统虽然记录了信息,但产生了太多无效告警,导致真正的攻击信号被淹没,无人关注。
防御与缓解措施
记录关键安全事件: 确保对登录(成功和失败)、权限变更、高价值交易、输入验证失败等关键事件进行审计日志记录。
日志内容标准化: 日志应包含足够的信息以便于溯源,如时间戳、源IP、用户ID、事件类型、操作对象等,并采用统一格式(如JSON)。
集中化日志管理: 将所有服务器和应用的日志发送到集中的、安全的日志管理系统(如ELK Stack, Splunk, SIEM),便于查询和分析。
建立有效的监控和告警: 基于日志数据,建立对可疑活动的监控仪表盘和告警规则。例如,短时间内大量登录失败、非工作时间的高权限操作等。
定期测试应急响应计划: 模拟安全事件,检验日志和监控系统是否能有效支持事件的发现、遏制和恢复。
攻击者视角
“一个没有监控的系统,就像一个黑暗的房间,我可以为所欲为,而且不会留下任何脚印。”
A10:2021 - 服务器端请求伪造 (SSRF)
核心问题
“我让你的服务器当了我的‘代理’,去攻击那些我本来碰不到的地方。”
风险解读
当Web应用程序在未对用户提供的URL进行充分验证的情况下,从远程资源获取内容时,就会出现SSRF漏洞。攻击者可以欺骗应用程序向其选择的目标发送一个伪造的请求。这使得攻击者能够利用服务器的身份和网络位置,去访问和攻击那些通常受防火墙保护、无法从外部直接访问的内部系统。
常见利用场景
探测内网: 利用“从URL上传图片”、“WebHook回调”、“PDF生成”等功能,输入内网地址如 http://192.168.1.1:8080,通过返回的错误信息或响应时间,绘制出内网的拓扑“地图”,发现开放的端口和服务。
攻击内网应用: 通过SSRF发现内网中一个未授权访问的Jenkins或Redis,构造URL让服务器代替自己去访问这些服务的API来执行命令或读取数据。
窃取云服务凭证: 在云环境中,通过SSRF让服务器去请求云元数据服务地址(如AWS的http://169.254.169.254/),窃取服务器的临时访问凭证(IAM Role Credentials),从而获得对整个云账户的控制权限。
绕过防火墙: 利用服务器作为跳板,向其他外部系统发起攻击,从而隐藏自己的真实IP地址。
防御与缓解措施
网络层隔离: 将处理外部请求的服务器放置在独立的网络区域,严格限制其对内网其他服务的访问权限。
应用层强制白名单: 建立一个安全的、允许访问的URL白名单(包括域名、IP、端口和协议)。拒绝所有不在此列表中的请求。黑名单策略(如禁止127.0.0.1)很容易被绕过。
禁用未使用的URL协议: 只允许HTTP和HTTPS协议,禁用file://、gopher://、dict://等危险的协议。
统一处理请求和响应: 不要将原始的响应体直接返回给用户,这会泄露内网信息。应用程序应该验证并解析响应,然后以安全的方式呈现所需数据。
不解析重定向: 在发起请求时,配置HTTP客户端库不自动跟随3xx重定向,防止攻击者绕过白名单。
攻击者视角
“你的服务器在内网里是‘自己人’,畅通无阻。我就躲在它身后,让它替我开路和办事。”
thumb_upthumb_down
arrow_upward_altarrow_downward_alt