大家好!👋 OWASP Top 10 征服系列,今天我们将讨论在2021年全新出现并引起大家关注的 A04:2021-不安全设计(Insecure Design)。
这个项目并非针对一行代码的错误,而是处理从一开始就设计图本身存在问题的根本性问题。无论用多么好的材料建造多么坚固的房子,如果设计图上缺少了玄关门锁,那也是徒劳的,对吧?📜✍️ 同样,’不安全设计’是一个非常重要且严重的问题,后期修改起来非常困难且成本高昂。

🤔 不安全设计?那是什么?
‘不安全设计’指的是在软件规划和设计阶段,未能充分考虑安全威胁而导致的所有类型的漏洞。
这与OWASP其他主要关注’不安全实现(Insecure Implementation)’的项目形成对比。
- 不安全实现:设计良好,但开发人员在编码时犯了错误。(例如:设计图上写着’钢制锁具’,但实际却用’塑料玩具锁’制作的情况)
- 不安全设计:从一开始设计图本身就存在问题。(例如:设计图上完全遗漏了’玄关门锁’的情况)
换句话说,任何在没有提出“这个功能可能如何被滥用?”这个问题的情况下创建的功能,都可能是不安全设计的结果。这个项目展示了在开发早期阶段就将安全纳入考虑的‘左移(Shift-Left)’概念的重要性。
🕵️♂️ 不安全设计的典型案例
在什么情况下我们可以说“设计不安全”呢?
1. 缺乏威胁建模(Lack of Threat Modeling)
这是最根本的问题。就像在建房子之前会考虑“小偷会如何进入?”、“发生火灾时如何疏散?”一样,在设计系统之前,预先识别可能发生的安全威胁并制定对策的过程称为威胁建模。
- 问题:如果开发在没有威胁建模的情况下开始,那么在不了解“我们服务的重要资产是什么?”、“谁能如何攻击?”的情况下创建功能。😥❓
- 结果:设计中遗漏了针对可预测攻击(例如:密码找回功能无限次尝试)的防御逻辑。
2. 有缺陷的业务逻辑(Flawed Business Logic)
代码本身没有bug,但服务的操作流程(Workflow)可能被滥用的情况。
- 案例 🛒💸:
- 在网上商城中,将价值10万韩元的商品A和1千韩元的商品B加入购物车。
- 应用仅适用于1千韩元商品B的50%折扣优惠券。(总支付金额:100,500韩元)
- 在支付前,从购物车中删除1千韩元的商品B。
- 如果系统设计有误,10万韩元的商品A可能仍然享受50%的折扣,导致以5万韩元支付的问题。
3. 缺乏速率限制(Rate Limiting)
系统未限制特定功能每小时请求次数的设计问题。
- 问题:如果在登录页面可以无限次尝试输入密码,会发生什么?攻击者可以使用自动化工具在短时间内尝试数亿个密码,从而窃取账户。(暴力破解攻击)💣
- 必要性:“登录尝试失败5次后账户锁定10分钟”、“每分钟API请求限制100次”等速率限制必须在设计阶段予以考虑。
4. 不可信的客户端控制
这是一种危险的设计,安全验证仅在用户浏览器(客户端)而非服务器上执行。
- 问题:假设我们使用JavaScript将“价格字段”设置为不可修改。普通用户无法修改,但攻击者可以利用浏览器开发者工具或代理工具轻松绕过此限制,将价格更改为0并发送到服务器。😲
- 原则:“永远不要相信客户端(Never trust the client)。”所有重要的数据验证和权限检查都必须设计为在服务器上再次执行。
🛡️ 如何进行安全设计?
- 引入安全开发生命周期(Secure SDLC)🔄:安全活动必须自然地整合到开发的各个阶段,包括需求分析、设计、开发、测试和部署。安全不是开发完成后才添加的功能。
- 威胁建模常态化 🧠💡:每次设计新功能时,都要与团队成员一起思考和讨论“这个功能最坏的情况是什么?”。利用STRIDE、DREAD等经过验证的方法论会很有帮助。
- 使用安全设计模式:
- 最小权限原则:为所有组件和用户仅授予必需的最小权限。
- 纵深防御:设计多层安全机制,即使一道防线被突破,下一道防线也能阻止攻击。
- 最小化攻击面:最小化暴露给外部的功能或API,以减少可能被攻击的点。
- 迭代审查和改进:设计并非一劳永逸。应与同事一起审查已创建的设计图,并随着新威胁信息的出现持续改进设计。
✨ 总结
不安全设计就像应用程序的“先天性心脏病”。如果后期发现,手术会非常复杂和危险。相反,在开发初期就考虑威胁并进行安全设计,是付出小努力就能阻止未来大灾难的最有效方法。
请记住“好的代码源于安全设计”这句话,希望我们所有人都能以“安全架构师”的心态投入到开发中!
发表回复