OWASP TOP 10的风险分析以及预防措施(前三个)
A01:2021-失效的访问控制 Broken Access Control 风险说明: 访问控制强制实施策略,使用户无法在其预期权限之外进行操作。失败的访问控制通常会导致未经授权的信息泄露、修改或销毁所有数据、或在用户权限之外执行业务能力。常见的访问控制脆弱包括:
- 违反最小特权原则或默认拒绝原则,即访问权限应该只授予特定能力、角色或用户,但实际上任何人都可以访问。
- 通过修改URL(参数篡改或强制浏览)、内部应用程序状态或HTML页面,或使用修改API请求的攻击工具来绕过访问控制检查
- 通过提供唯一标识符(不安全的直接对象引用)允许查看或编辑其他人的账户
- API没有对POST、PUT和DELETE强制执行访问控制
- 特权提升。在未登录的情况下假扮用户或者以用户身份登陆时充当管理员
- 元数据操作。例如通过重放或篡改JSON Web令牌(JWT)来访问控制令牌,或操纵cookie或隐藏字段以提升权限,或滥用JWT失效
- CORS配置错误导致允许未授权或不可信的API访问。
- 以未通过身份验证的用户身份强制浏览的通过身份验证时才能看到的页面或作为标准用户身份访问特权页面
预防措施: 访问控制只在受信服务器端代码或无服务器API中有效,这样攻击者才无法修改访问控制检查或元数据。
- 除公有资源外,默认为“拒绝访问”
- 使用一次性的访问控制机制,并在整个应用程序中不断重用它们,包括最小化跨源资源共享(CORS)的使用。
- 建立访问控制模型以强制执行所有权记录,而不是简单接受用户创建、读取、更新或删除的任何记录
- 特别的业务应用访问限制需求应由领域模型强制执行
- 禁用Web服务器目录列表,并确保文件元数据(例如:.git)和备份文件不存在于Web的根目录中
- 在日志中记录失败的访问控制,并在适当时向管理员告警(例如:重复故障)
- 对API和控制器的访问进行速率限制,以最大限度地降低自动化攻击工具带来的危害
- 当用户注销后,服务器上的状态会话标识符应失效。无状态的JWT令牌应该是短暂的,以便让攻击者的攻击机会窗口最小化。对于时间较长的JWT,强烈建议遵循OAuth标准来撤销访问
开发人员和QA人员应进行访问控制功能的单元测试和集成测试
攻击范例:
- 应用程序在访问帐户信息的SQL调用中使用了未经验证的数据: pstmt.setString(1, request.getParameter(“acct”)); ResultSet results =
pstmt.executeQuery( ); 攻击者只需修改浏览器的“acct”参数即可发送他们想要的任何帐号。如果没有正确验证,攻击者可以访问任何用户帐户。 https://example.com/app/accountInfo?acct=notmyacct - 攻击者仅强制浏览目标URL。 访问管理页面一定需要管理员权限。 https://example.com/app/getappInfo https://example.com/app/admin_getappInfo
如果一个未经身份验证的用户可以访问任何页面,那么这是一个缺陷。 如果一个非管理员权限的用户可以访问管理页面,那么这同样也是一个缺陷。
A02:2021-加密机制失效 Cryptographic Failures 风险说明: 首先要确认:对传输中数据和存储数据都有哪些保护需求。例如,密码、信用卡号、医疗记录、个人信息和商业秘密需要额外保护,尤其是在这些数据属于隐私保护法(如:欧盟GDPR)或法规条例(如:金融数据保护标准PCI DSS)适用范围的情况下。对于这些数据,要确定:
- 在传输数据过程中是否使用明文传输?这和传输协议有关,如:HTTP、SMTP、经过TLS升级(如STARTTLS)的FTP。外部网络流量是有害的。需要验证所有的内部通信,如,负载平衡,Web服务器或后端系统之间的流量。
- 无论是在默认情况下还是在旧的代码中,是否还在使用任何旧的或脆弱的加密算法或传输协议?
- 是否使用默认加密密钥、生成或重复使用脆弱的加密密钥,或者是否缺少适当的密钥管理或密钥回转?加密密钥是否已经提交到源代码存储库?
- 是否未执行强制加密,例如,是否缺少安全的HTTP(浏览器)指令或标头?
- 接收到的服务器证书和信任链是否经过正确验证?
- 初始化向量是否忽略,重用或生成的密码操作模式是否不够安全?是否正在使用不安全的操作模式,例如欧洲央行正在使用的操作模式?当认证加密更合适时是否使用加密?
- 在缺乏密码基密钥派生函数的情况下,是否将密码用作加密密钥?
- 随机性是否用于并非旨在满足加密要求的加密目的?即使选择了正确的函数,它是否需要由开发人员播种,如果不需要,开发人员是否用缺乏足够熵/不可预测性的种子覆盖了内置的强大播种功能?
- 是否使用过时的散列函数,例如MD5或SHA1,或者在散列函数需要加密时使用非加密散列函数?
- 是否使用已弃用的加密填充方法,例如PCKS number 1 v1.5?
- 加密的错误消息或测信道信息是否可以利用,例如使用填充预言机攻击的形式?
请参考OWASP ASVS中的Crypto加密(V7)、Data Protection数据保护(V9)和SSL/TLS(V10)
预防措施: 至少执行以下操作,并查阅参考资料:
- 对应用程序处理、存储或传输的数据分类,并根据隐私法、监管要求或业务需求确定哪些数据是敏感的。
- 对于没有必要存储的敏感数据,应当尽快清除,或者通过PCI DSS标记化或拦截。未存储的数据不能窃取。
- 确保加密存储的所有敏感数据
- 确保使用了最新的、强大的标准算法、协议和密钥;并且密钥管理到位
- 确保加密传输过程中的数据,如使用安全协议(例如具有前向保密(FS)密码的TLS、服务器的密码优先级和安全参数)。确保强制执行数据加密,如使用HTTP严格安全传输协议(HSTS)等指令
- 禁用缓存对包含敏感数据的响应
- 根据数据分类应用实施所需的安全控制
- 不要使用FTP和SMTP等传统协议来传输敏感数据
- 使用具有工作因子(延迟因子)的强自适应和加盐散列函数存储密码,例如Argon2、scrypt、bcrypt或PBKDF2
- 必须选择适合操作模式的初始化向量。对于大多数模式,可以使用CSPRNG(密码安全伪随机数生成器)。对于需要随机数的模式,则初始化向量(IV)不需要使用CSPRNG。在所有情况下,对于一个固定密钥,永远不应该使用两次IV
- 始终使用经过验证的加密,而不仅仅是加密
- 密钥应以加密方式随机生成并作为字节数组存储在内存中。如果使用密码,则必须通过适当的密码基密钥派生函数将其转换为密钥
- 确保在适当的地方使用加密随机性,并且没有以可预测的方式或低熵进行播种。大多数现代PI不需要开发人员为CSPRNG设置种子以获得安全性。
- 避免使用的已废弃的加密函数和填充方案,例如MD5、SHA1、PKCS number 1 v1.5
- 单独验证每个安全配置项的有效性
攻击范例:
- 一个应用程序使用自动化的数据加密系统加密存储数据库中的信用卡号。 但是,这些数据在检索时会自动解密,这就使得SQL 注入漏洞以明文形式获得信用卡号。
- 一个网站对所有网页没有使用或对强制使用TLS,或者使用弱加密。攻击者经过监测网络流量(例如,在不安全的无线网络中),将网络连接从HTTPS降级到HTTP,就可以拦截请求并窃取用户会话cookie。之后,攻击者重放这个cookie并劫持用户的(经过身份验证的)会话,访问或修改用户的私人数据。除此之外,攻击者还可以更改所有传输过程中的数据,例如,汇款的接收人
- 密码数据库使用未加盐或弱哈希算法来存储每个人的密码。一个文件上传漏洞允许攻击者获取密码数据库。所有未加盐哈希的密码都可以通过预先计算的哈希值彩虹表破解。由简单或快速散列函数生成的加盐哈希也可能通过GPU破解
A03:2021-注入 Injection 风险说明: 在以下情况下,应用程序容易受到攻击:
- 应用程序不会验证、过滤或清洗用户提供的数据
- 动态查询或无上下文感知转移的非参数化调用直接在解释器中使用
- 恶意数据在对象关系映射(ORM)搜索参数中用于提取额外的敏感记录
- 恶意数据被直接使用或连接。SQL或命令包含动态查询、命令或存储过程中的结构和恶意数据
一些更常见的注入包括:SQL、NoSQL、OS命令、对象关系映射(ORM)、LDAP和表达式语言(EL)或对象图导航库(OGNL)注入。这一概念在所有解析器中都是相同的。源代码审查是检测应用程序是否易受注入共计的最佳方法。强烈鼓励针对所有参数、标题、URL、cookies、JSON、SOAP和XML数据输入的自动测试。组织可以在CI/CD管道中引入静态(SAST)、动态(DAST)和交互式(IAST)应用程序安全测试工具,以在产品部署之前识别引入的注入缺陷。
预防措施: 防止注入需要将数据与命令和查询分开:
- 推荐的选择是使用安全的API,这样可以避免完全使用解释器、提供参数化接口或迁移到对象关系映射工具(ORM)。注意:即使参数化,如果PL/SQL或T-SQL将查询和数据连接起来,或者使用EXECUTE IMMEDIATE或exec()执行恶意数据,则存储过程仍然可以引入SQL注入。
- 使用肯定(positive)或“白名单”服务器端输入验证。这并不是一种完美的防御,因为许多应用程序需要对特殊字符,例如移动应用程序中的文本区域或API
- 对于任何残余的动态查询,请使用该解释器的特定转义语法转义特殊字符。注意:SQL结构(如表名、列名等)无法转义,因此用户提供的结构名是危险的。这是报表编写软件中的常见问题。
- 在查询中使用LIMIT和其他SQL控件,以防止在SQL注入的情况下大量披露记录。
攻击范例:
- 应用程序在构造以下易受共计的SQL调用时使用不受信任的数据: String query = “SELECT FROM accounts WHERE custID='” + request.getParameter(“id”) + “'” ";
- 应用程序对框架的盲目信任可能会导致易受共计的查询(例如,Hibernate查询语言(HQL)) Query HQLQuery = session.createQuery(“FROM accounts WHERE custID='” +
request.getParameter(“id”) + “'”); 在这 两种情况下,攻击者都会修改浏览器中的"id"参数值,例如下图,这将更改两个查询的含义,以返回accounts表中的所有记录。更危险的攻击可能会修改或删除数据,甚至调用存储过程
|