访问控制强制实施策略可以使用户无法在其权限之外进行操作。(只能做有权限的操作),失败的访问控制会导致未经授权的信息泄露、修改或销毁所有数据、或在用户权限外执行业务功能。常见的访问控制脆弱点包括:
违法最小特权原则或默认拒绝原则
通过修改URL(参数篡改或强制浏览)、内部应用程序状态、使用修改API请求的攻击工具来绕过访问控制检查
通过提供唯一标识符允许查看或编辑其他人的账户
API没有对POST、PUT、DELETE强制执行访问控制
特权提升,在未登录的情况下假扮用户或以用户身份登陆时充当管理员(垂直越权)
元数据操作,例如通过重放或篡改 JSON Web 令牌 (JWT) 来访问控制令牌,或操纵cookie 或隐藏字段以提升权限,或滥用 JWT 失效
CORS 配置错误以致允许未授权或不可信的API访问 (最小化跨院资源共享)
以未通过身份验证的用户身份强制浏览的通过身份验证时才能看到的页面或作为标准用户身份访问特权页面
访问控制只在受信服务器端代码或无服务器API中有效, 这样攻击者才无法修改访问控制检查或元数据
除了公有资源,其他默认为拒绝访问
建立访问控制模型以强制执行所有权记录
使用一次性访问控制机制
特别的业务应用访问限制需求应由领域模型强制执行
确保备份文件不存在web根目录中
对API和控制器的访问进行速率进行限制
当用户注销后,服务器上的状态会话标识符应失效
范例1:应用程序在访问账户信息的sql调用了未经验证的数据
pstmt.setString(1, request.getParameter("acct")); #攻击者只需修改acct参数,即可发送想要的任何账户
ResultSet results = pstmt.executeQuery( ); #没有正确验证,攻击者可以访问任何用户账户
范例2:访问管理页面一定要由管理员权限
https://example.com/app/getappInfo #如果一个未经身份验证的用户可以访问任何页面,就是缺陷
https://example.com/app/admin_getappInfo #如果一个非管理员的用户可以访问管理页面,就是一个缺陷
需要确定哪些数据需要保护,例如:密码、个人信息等等。
传输过程是否明文传输
旧的脆弱的加密算法或传输协议
使用默认加密密钥、生成或重复使用脆弱的加密密钥
未执行强制加密,HTTP(S)
对于没有必要存储的敏感数据应尽快清除
确保加密存储的所有敏感数据
确保使用强大的算法、协议和密钥
确保加密传输过程中的数据,如安全协议
禁用缓存对包含敏感数据的响应
不要使用FTP和SMTP等传统协议来传输敏感数据
使用具有工作因子(延迟因子)的强自适应和加盐散列函数存储密码
始终使用经过验证的加密,而不仅仅是加密
密钥应以加密方式随机生成并作为字节数组存储在内存中
避免使用的已废弃的加密函数和填充方案,如MD5、SHA1
单独验证每个安全配置项的有效性
范例1
一个应用程序使用自动化的数据加密系统加密存储中数据库中的信用卡号。 但是, 这些数据在检索时会自动解密,这就使得SQL 注入漏洞以明文形式获得信用卡号
范例2
一个网站对所有网页没有使用或对强制使用TLS ,或者使用弱加密。 攻击者经过监测网络流量(例如, 在不安全的无线网络中) , 将网络连接从 HTTPS 降级到 HTTP, 就可以拦截请求并窃取用户会话cookie。 之后, 攻击者重放这个cookie 并劫持用户的(经过身份验证的) 会话,访问或修改用户的私人数据。
范例3
密码数据库使用未加盐或弱哈希算法来存储每个人的密码。 一个文件上传漏洞允许攻击者获取密码数据库。 所有未加盐哈希的密码都可以通过预先计算的哈希值彩虹表破解。 由简单或快速散列函数生成的加盐哈希也可能通过GPU 破解。
在以下情况下,应用程序易受攻击:
应用程序不会验证、过滤或清洗用户提供的数据
动态查询或无上下文感知转义的非参数化调用直接在解释器中使用
恶意数据在对象关系映射搜索参数中用于提取额外的敏感记录
恶意数据被直接使用或连接。SQL或命令包含动态查询、命令或存储过程中的结构和恶意数据
防止注入需要将数据与命令和查询分开:
使用安全的API,可以避免安全使用解释器、提供参数化接口或迁移到对象关系映射工具。注意:即使参数化, 如果PL/SQL或T-SQL将查询和数据连接起来, 或者使用EXECUTE IMMEDIATE或exec() 执行恶意数据, 则存储过程仍然可以引入SQL注入。
使用肯定(positive) 或“白名单” 服务器端输入验证。 这并不是一种完美的防御, 因为许多应用程序需要特殊字符, 例如移动应用程序中的文本区域或API。
对于任何残余的动态查询, 请使用该解释器的特定转义语法转义特殊字符。 注意: SQL结构(如表名、 列名等) 无法转义, 因此用户提供的结构名是危险的。 这是报表编写软件中的常见问题。
在查询中使用LIMIT和其他SQL控件, 以防止在SQL注入的情况下大量披露记录
范例1
应用程序在构造以下易受攻击的SQL调用时使用不受信任的数据:String query = "SELECT \* FROM accounts WHERE custID='" + request.getParameter("id") + "'";
范例2
类似地, 应用程序对框架的盲目信任可能会导致易受攻击的查询(例如, Hibernate查询语言(HQL))Query HQLQuery = session.createQuery("FROM accounts WHERE custID='" + request.getParameter("id") + "'");在这两种情况下, 攻击者都会修改浏览器中的“id” 参数值,以发送: '或'1'='1。 例如: http://example.com/app/accountView?id=' or '1'='1这将更改两个查询的含义, 以返回accounts表中的所有记录。更危险的攻击可能会修改或删除数据, 甚至调用存储过程。
不安全设计比较广泛,代表不同的弱点,表示为缺少或无效的控制设计。导致不安全设计的因素之一是开发的软件或系统中缺乏固有的业务风险分析,因此无法确定需要何种级别的安全设计。
需求和资源管理
安全设计
安全开发生命周期(SAMM)
与应用安全专业人员建立并使用安全的开发生命周期, 以帮助评估和设计与安全和隐私相关的控制。
建立并使用安全设计模式的库, 或使用AppSec规划中现有的要素。
对关键身份验证、 访问控制、 业务逻辑和密钥流使用威胁建模。
将安全语言和安全控制集成到用户故事中。
在应用程序的每一层(从前端到后端) 集成合理性检查。
编写单元和集成测试, 以验证所有关键流是否能够抵抗威胁模型。 为应用程序的每一层编译正确用例和误用案例。
根据暴露和保护需要, 对系统层和网络层进行分层。
通过设计在所有层中严格隔离租户。
限制用户或服务的资源消耗。
范例1
身份凭证恢复工作流可能包括NIST 800-63b 、 OWASP ASVS和OWASP Top 10中已禁止的“问题和答案” 功能。“问题和答案” 不能作为可信的证据来证明身份, 因为不止一个人知道答案, 这就是为什么它们被禁止的原因。 应删除此类代码, 并用更安全的设计替换
范例2
一家连锁电影院允许团体预订折扣, 支持最多15名观众而不要押金。 攻击者可以对这种流量进行威胁建模, 并测试他们是否可以在几个请求中同时预订600个座位和所有电影院,从而造成巨大的收入损失
范例3
零售连锁店的电子商务网站没有针对黄牛党运行的机器人的保护, 黄牛党购买高端显卡然后在拍卖网站上销售。 这给显卡制造商和零售连锁店老板创造了糟糕的形象, 并与那些无法以任何价格获得这些卡的爱好者产生了持久的伤害。 适当的反机器人设计和域逻辑规则,例如在可用的几秒钟内进行的购买, 可能会被识别为不可信的购买并拒绝此类交易。
应用程序可能受到攻击,如果应用程序是:
应用程序栈的任何部分缺少适当的安全加固,或者云服务的权限配置错误
应用程序启用或安装了不必要的功能(例如:不必要的端口、服务、网页、账户或权限)
默认账户和密码仍然可用且没有更改
错误处理机制向用户纰漏堆栈信息或其他大量错误信息
对于升级的系统,最新的安全特性被禁用或未安全配置
应用程序服务器、应用程序框架、库文件、数据库等没有进行安全配置
服务器不发送安全标头或指令,或未被设定安全参数
应用软件已过期或易受攻击
缺少一个体系的、 可重复的应用程序安全配置过程, 系统将处于高风险中
应实施安全的安装过程, 包括:
一个可以快速且易于部署在另一个锁定环境的可重复的加固过程。 开发、 质量保证和生产环境都应该进行相同配置, 并且在每个环境中使用不同的密码。 这个过程应该是自动化的, 以尽量减少安装一个新安全环境的耗费。
搭建最小化平台, 该平台不包含任何不必要的功能、 组件、 文档和示例。 移除或不安装不适用的功能和框架。
检查和修复安全配置项来适应最新的安全说明、 更新和补丁, 并将其作为更新管理过程的一部分。 在检查过程中, 应特别注意云存储权限(如: S3桶权限) 。
一个能在组件和用户间提供有效的分离和安全性的分段应用程序架构, 包括:分段、 容器化和云安全组(ACL) 。
向客户端发送安全指令, 例如:安全标头。
一个能够验证所有环境中进行了正确的安全配置和设置的自动化过程。
范例1
应用程序服务器附带了未从产品服务器中删除的应用程序样例。这些样例应用程序具有已知的安全漏洞,攻击者利用这些漏洞来攻击服务器。 假设其中一个应用程序是管理员控制台, 并且没有更改默认账户,攻击者就可以通过默认密码登录, 从而接管服务器
范例2
目录列表在服务器端未被禁用。 攻击者发现他们很容易就能列出目录列表。 攻击者找到并下载所有已编译的Java类, 他们通过反编译来查看代码。然后, 攻击者在应用程序中找到一个严重的访问控制漏洞
范例3
应用程序服务器配置允许将详细的错误信息( 如:堆栈信息)返回给用户, 这可能会暴露敏感信息或潜在的漏洞, 如:已知含有漏洞的组件的版本信息。
范例4
云服务提供商向其他CSP用户提供默认的网络共享权限。 这允许攻击者访问存储在云端的敏感数据
如果满足下面某个条件,说明应用易受到此类攻击:
如果您不知道所有使用的组件版本信息(包括:服务端和客户端) 。 这包括了直接使用的组件或间接依赖的组件。
如果软件易受攻击, 不再支持或者过时。 这包括:系统、 Web服务器、 应用程序服务器、 数据库管理系统(DBMS) 、 应用程序、 API和所有的组件、 运行环境和库。
如果您没有定期做漏洞扫描和订阅使用组件的安全公告。
如果您不基于风险及时修复或升级底层平台、 框架和依赖库。 很可能发生这种情况:根据变更控制,每月或每季度进行升级, 这使得组织在这段时间内会受到已修复但未修补的漏洞的威胁。
如果软件工程师没有对更新的、 升级的或打过补丁的组件进行兼容性测试。
如果您没有对组件进行安全配置
应制定一个补丁管理流程:
移除不使用的依赖、 不需要的功能、 组件、 文件和文档。
利用如versions、 OWASP Dependency Check、 retire.js等工具来持续的记录客户端和服务器端以及它们的依赖库的版本信息。 持续监控如CVE和NVD等是否发布已使用组件的漏洞信息, 可以使用软件分析工具来自动完成此功能。 订阅关于使用组件安全漏洞的警告邮件。
仅从官方渠道安全的获取组件, 并使用签名机制来降低组件被篡改或加入恶意漏洞的风险
监控那些不再维护或者不发布安全补丁的库和组件。 如果不能打补丁, 可以考虑部署虚拟补丁来监控、 检测或保护
每个组织都应该制定相应的计划, 对整个软件生命周期进行监控、 评审、 升级或更改配置。
范例1
通常组件都是以与应用相同的权限运行的,这使得组件里的缺陷可能导致各式各样的问题。这些缺陷可能是偶然的(如:编码错误),也可能是蓄意的(如:组件里的后门)。下面是一些已被利用的漏洞:CVE-2017-5638,一个Struts2远程执行漏洞。可在服务端远程执行代码,并已造成巨大的影响。虽然物联网(IoT)设备一般难以通过打补丁来修复。但对它打补丁非常重要(例如:医疗设备)。有些自动化工具能帮助攻击者发现未打补丁的或配置不正确的系统。例如: Shodan IOT搜索引擎能帮助您发现从2014年4月至今仍存在心脏出血漏洞的设备
之前称之为“无效的身份认证”
允许攻击者已经拥有有效用户名和密码列表的撞库自动化攻击
允许暴力或其他自动化攻击
允许预设、 脆弱、 常见的密码, 像是"Password1"或"admin/admin"。
使用脆弱或无效的认证资讯回复或忘记密码的流程, 如不安全的"知识相关问答"。
使用明码、 被加密的或使用较脆弱杂凑法的密码(参考A3: 2017-敏感性资料泄漏)。 (TODO)https://github.com/OWASP/Top10/issues/553
不具有或是无效的多因素认证。
于URL中泄漏会话(session) ID(如URL重写)。
成功登入后没有轮换会话(session) ID。
没有正确的注销会话 (session) ID。 用户的会话 (session) 或认证 tokens( 主要是单一登入(SSO)token) 没有在登出时或一段时间没活动时被适当的注销
在可能的情况下, 实施多因素认证来防止自动化撞库攻击、 暴力破解、 以及遭窃认证资讯被重复利用的攻击。
不要交付或部署任何预设的认证凭证, 特别是管理者。
实施弱密码的检查, 如测试新设定或变更的密码是否存在于前10000个最差密码清单。
将密码长度、 复杂度和轮换政策与NIST 800-63b文件
对所有结果使用相同的讯息回应, 确保注册、 认证凭据回复以及API路径能够抵御帐号枚举攻击。
限制或增加登入失败尝试的延迟。 记录所有失败并于侦测到撞库、 暴力破解或其他攻击时发出告警。
使用服器端、 安全的内建会话管理器, 在登入后产生有高熵值的新随机会话ID。 会话ID不应出现在URL中, 必须被安全的储存, 并且在登出后、 闲置、 超时后被注销
范例1
使用已知列表密码的撞库攻击是一种常见的攻击方式,假设应用沒有实施自动化威胁或撞库攻击的保护,在这种情況下,应用会被利用为密码预报的工具来判断认证凭据是否有效。
范例2
大多数身份验证攻击都是由于密码作为单一因素持续使用而发生的。一旦考虑,最佳实践、密码轮换和复杂性要求鼓励用户使用和重用弱密码。 建议组织按照NIST 800-63停止这些做法并使用多因素认证。
范例3
应用会话超时设置错误。 一个用户使用公用电脑来访问应用时,用户没有选择“登出” 而是简单的关闭浏览器标签页就离开。一小时后, 一个攻击者使用同一个浏览器, 而那个应用仍处于前面用户认证通过的状态。
软件和数据完整性故障与无法防止违反完整性的代码和基础设施有关。
这方面的一个例子是,应用程序依赖于不受信任的源、 存储库和内容分发网络( CDN) 的插件、 库或模块。 不安全的CI/CD管道可能会带来未经授权的访问、 恶意代码或系统安全风险。 最后, 许多应用程序现在包括自动更新功能。 其中, 更新包在没有进行充足完整性验证的情况下被下载, 并应用于以前受信任的应用程序。 攻击者可能会上传自己的更新包, 以便在所有安装上分发和运行。 另一个例子是, 对象或数据被编码或序列化为攻击者可以看到和修改的结构, 很容易受到不安全的反序列化的影响。
使用数字签名或类似机制来验证软件或数据来自预期来源, 且未被修改。
确保库和依赖项目, 如: npm 或 Maven, 正在使用受信任的存储库。 如果您的风险较高, 请考虑托管一个经过审核的、 内部已知合格的存储库。
确保使用软件供应链安全工具(如: OWASP Dependency Check 或 OWASP CycloneDX) 来验证组件不包含已知漏洞。
确保对代码和配置更改进行审核, 以最大限度地减少恶意代码或配置引入软件管道的可能性。
确保您的CI/CD管道具有适当的隔离、 配置和访问控制, 以确保代码在构建和部署过程中的完整性。
确保通过特定形式的完整性检查或数字签名来检测序列化数据是否存在篡改或重播, 所有未签名或未加密的序列化数据不会发送到不受信任的客户端
范例1、无需签名即可更新
许多家庭路由器、机顶盒、设备固件和其他设备通过没有签名的固件进行更新。未签名固件是越来越多的攻击者的目标,预计情况只会变得更糟。这是一个主要问题,因为很多时候除了在未来的版本中修复和等待以前的版本过期之外,没有任何其他补救措施
范例2、SolarWinds恶意更新
众所周知一种新的攻击机制,即, 最近值得注意的SolarWinds Orion攻击。开发该软件的公司具有安全的构建和更新完整性流程。尽管如此,这些都能够被颠覆。几个月来,该公司向18,000多个组织分发了一个高度针对性的恶意更新,其中大约100个组织受到影响。这是历史上同类性质中影响最深远和最严重的违规行为之一。
范例3、不安全的反序列化
一个React 应用程序调用一组Spring Boot 微服务。作为函数程序员,他们试图确保他们的代码是不可变的。他们提出的解决方案是将用户状态序列化,并在每个请求中来回传递。攻击者注意到“rO0”Java 对象签名(在 base64 中),并使用 Java Serial Killer工具在应用服务器上获取远程代码执行权。
2021年版OWASP Top 10中, 该类别是为了帮助检测、 升级和应对活跃的违规行为。 如果不进行日志记录和监测, 就无法发现违规行为。 任何时候都会发生日志记录、 检测、 监视和主动响应不足的情况:
需要审计的事件, 例如:登录、 失败的登录和高价值交易, 但未记录。
警告和错误未生成日志或日志记录不充分或日志消息不清晰。
应用程序和 API的日志未进行安全可疑活动的监控。
日志只存储在本地。 适当的警报阈值和响应升级过程不到位或无效。
渗透测试和动态应用安全测试(DAST) 工具(例如: OWASP ZAP) 的扫描没有触发警报。
应用无法实时或接近实时地检测、 升级或或对主动攻击发出警报。
如果让用户或攻击者看到日志和警报事件, 您就容易受到信息泄露的攻击
开发人员应根据应用的风险, 实施以下部分或全部控制:
确保所有的登录、 访问控制和服务器端输入验证失败都可以被记录在足够的用户上下文中, 以识别可疑或恶意的帐户, 并保留足够的时间以允许延迟的取证分析。
确保日志是日志管理解决方案以方便使用的格式生成的。
确保日志数据被正确编码加密, 以防止对日志或监控系统的注入或攻击。
确保高价值交易有完整性控制的审计跟踪, 以防止篡改或删除, 例如:只附加数据库表或类似的内容。 DevSecOps团队应该建立有效的监控和警报, 以便发现可疑的活动并迅速做出反应。
建立或采用事故应对和恢复计划, 例如:美国国家标准技术研究所(NIST)800-61r2或更高版本。
有一些商业和开源的应用程序保护框架, 如: OWASP ModSecurity核心规则集, 以及开源的日志相关软件, 如: Elasticsearch、 Logstash、 Kibana(ELK) , 具有自定义仪表盘和告警功能。
范例1
一家儿童健康计划供应商的网站运营者由于缺乏安全监控和记录而无法发现漏洞。一个外部团体告知儿童健康计划供应商,某恶意攻击者已经获取并修改了超过350万儿童的数千份敏感健康记录。事后审查发现,网站开发人员没有修复重大漏洞。由于没有对系统进行日志记录或监控,因此数据泄露可能自2013年以来一直在进行,时间超过7年
范例2
印度一家大型航空公司发生数据泄露事件,涉及数百万乘客十多年的个人信息,包括护照和信用卡信息。数据泄露发生在一家第三方云托管服务提供商,该提供商在一段时间后通知了航空公司此次泄露事件
范例3
欧洲一家大型航空公司遭遇一起 可报告的GDPR违规事件。据报道,攻击者利用支付应用程序的安全漏洞,获取了超过40万客户的支付记录,从而导致了此次攻击。该航空公司因此被隐私监管机构处以2000万英镑的罚款
一旦Web应用在获取远程资源时没有验证用户提供的URL, 就会出现SSRF缺陷。 它允许攻击者强制应用程序发送一个精心构建的请求到一个意外目的地, 即使是在有防火墙、 VPN或其他类型的网络访问控制列表(ACL) 保护的情况下。
随着现代Web应用为终端用户提供便利的功能, 获取URL成为一种常见的场景。 因此, SSRF安全攻击事件也在不断增加。 此外, 由于云服务和架构的复杂性, SSRF的严重性也越来越高。
纵深防御来组织SSRF:
网络层防御建议:
在隔离的网络中设置多个远程资源访问功能的网段, 以减少SSRF的影响。
执行“默认拒绝” 防火墙策略或网络访问控制规则, 以阻止除必要的内部网通信外的所有通信。
提示:
建立基于应用的防火墙规则的所有权和生命周期。
在防火墙上记录所有接受和阻止的网络流。
应用层防御建议:
检查和验证所有客户端提供的输入数据。
使用白名单允许列表允许列表执行URL统一资源标志符、 端口和目标。
不要给客户端发送原始的回复。
禁用 HTTP 重定向。
注意URL的一致性, 以避免DNS重新绑定和“检查时间, 使用时间” (TOCTOU)竞争条件等攻击。
不要通过使用黑名单拒绝列表或正则表达式来缓解SSRF。 攻击者拥有有效载荷列表、 工具和绕过拒绝列表的技能。
需额外考虑的措施:
不要在前端系统上部署其他与安全相关的服务(如: OpenID) 。 控制这些系统上的本地流量(如:localhost) 。
对于专用和可管理的前端用户, 可以在独立系统上使用网络加密(如: ) 来满足非常高的安全保护需求。
范例1、内部服务器端口扫描
如果网络架构未进行网络隔离,攻击者可以访问并绘制出内部网络地图,并根据连接结果或SSRF有效载荷连接的运行时间和拒绝时间判断内部服务器端口是打开还是关闭
范例2、敏感数据泄露
攻击者可以访问本地文件或内部服务,以获得敏感信息,例如: file:///etc/passwd span> http://localhost:280 17/
范例3、访问云服务的元数据存储
大多数云服务提供商都有元数据存储,比如:通过 http://169.254.169.254 /访问。攻击者可以通过读取元数据来获取敏感信息。
范例4、危害内部服务
攻击者可以滥用内部服务进行进一步的攻击,比如:远程代码执行(RCE)或者拒绝服务攻击(DoS)