OWASP 应用程序安全验证标准 4.0.3
控制项模式应用安全验证标准是一份应用安全需求或测试清单,可供架构师、开发人员、测试人员、安全专家、工具供应商和用户用来定义、构建、测试和验证安全应用程序。
验证使用安全的软件开发生命周期,在开发的所有阶段都考虑到安全性。(C1)
验证在每次设计变更或冲刺计划中使用威胁建模,以识别威胁、制定应对措施、促进适当的风险响应,并指导安全测试。
确保所有用户故事和功能都包含功能性安全约束,例如“作为用户,我应该能够查看和编辑我的个人资料,但我不应该能够查看或编辑其他人的个人资料”
验证所有应用程序的信任边界、组件和重要数据流的文档和理由。
验证应用程序高层架构及所有连接的远程服务的定义和安全分析。(C1)
验证集中化、简洁(设计经济)、经过审查、可靠且可重复使用的安全控制的实施,以避免重复、遗漏、无效或不安全的控制。(C10)
向所有开发人员和测试人员确认安全编码清单、安全需求、指南或政策的可用性。
验证所有应用程序组件、服务和服务器是否使用唯一或特殊的低权限操作系统帐户。(C3)
验证应用程序组件之间的通信,包括 API、中间件和数据层,是否经过身份验证。组件应具有所需的最低权限。(C3)
确保该应用程序使用已验证的、安全的单一身份验证机制,该机制可以扩展以包含强身份验证,并且具有足够的日志记录和监控功能以检测账户滥用或泄露。
验证所有身份验证途径和身份管理 API 是否实施了一致的身份验证安全控制强度,以确保根据应用程序的风险不存在较弱的替代方案。
验证受信的执行点(例如访问控制网关、服务器和无服务器函数)是否执行访问控制。切勿在客户端执行访问控制。
[已删除,不可执行]
[已删除,重复 4.1.3]
验证应用程序是否使用单一且经过充分审核的访问控制机制来访问受保护的数据和资源。所有请求都必须通过这一单一机制,以避免复制粘贴或不安全的替代路径。(C7)
验证是否使用基于属性或特性的访问控制,即代码检查用户对某个功能/数据项的授权,而不仅仅是他们的角色。权限仍应通过角色分配。 (C7)
确认输入和输出要求清楚地定义了如何根据类型、内容以及适用的法律、法规和其他政策遵从性来处理和处理数据。
在与不受信任的客户端通信时,确保不使用序列化。如果无法避免使用,请确保执行足够的完整性控制(如果传输敏感数据,可能还需要加密)以防止反序列化攻击,包括对象注入。
验证在受信任的服务层上是否执行了输入验证。(C5)
验证输出编码是否在接近或由其预期的解释器处进行。(C4)
验证是否存在用于加密密钥管理的明确政策,并且加密密钥的生命周期是否遵循诸如 NIST SP 800-57 等密钥管理标准。
验证加密服务的使用者是否通过使用密钥库或基于 API 的替代方案来保护密钥材料和其他机密信息。
验证所有密钥和密码是否可替换,并且是否属于重新加密敏感数据的明确定义的流程的一部分。
验证架构是否将客户端机密(如对称密钥、密码或 API 令牌)视为不安全,并且从不使用它们来保护或访问敏感数据。
确认系统中使用的是统一的日志记录格式和方法。(C9)
验证日志是否安全地传输到优选的远程系统以进行分析、检测、警报和升级。(C9)
确认所有敏感数据已被识别并分类到相应的保护等级。
确保所有保护级别都有相应的保护要求集合,例如加密要求、完整性要求、保留、隐私和其他机密性要求,并且这些要求已在架构中应用。
验证应用程序是否对组件之间的通信进行加密,尤其是当这些组件位于不同的容器、系统、站点或云服务提供商时。(C3)
验证应用程序组件是否能够验证通信链路中各方的真实性,以防止中间人攻击。例如,应用程序组件应验证 TLS 证书及其链。
确认使用了源代码控制系统,并且有程序确保提交代码时附带问题或变更单。源代码控制系统应具有访问控制和可识别的用户,以便追踪任何更改。
验证所有应用程序组件的定义和文档,确认其提供的业务或安全功能。
确保所有高价值业务逻辑流程,包括身份验证、会话管理和访问控制,不共享未同步的状态。
验证所有高价值的业务逻辑流程,包括身份验证、会话管理和访问控制,是否是线程安全的,并能抵抗检查时间与使用时间的竞争条件。
[已删除,重复 12.4.1]
验证用户上传的文件——如果需要在应用程序中显示或下载——是否通过八位字节流下载提供,或者从无关的域(例如云文件存储桶)提供。实施合适的内容安全策略(CSP)以降低上传文件引发的 XSS 向量或其他攻击的风险。
通过明确的安全控制、防火墙规则、API 网关、反向代理、基于云的安全组或类似机制,验证不同信任级别组件的隔离情况。
验证是否使用二进制签名、受信任的连接和已验证的端点来将二进制文件部署到远程设备。
验证构建流水线是否会对过时或不安全的组件发出警告并采取适当的措施。
确认构建管道中包含一个构建步骤,以自动构建并验证应用程序的安全部署,尤其是在应用程序基础设施是软件定义的情况下,例如云环境的构建脚本。
验证应用程序部署是否充分进行了沙箱化、容器化和/或网络级别隔离,以延迟并阻止攻击者攻击其他应用程序,尤其是在执行反序列化等敏感或危险操作时。(C5)
验证应用程序未使用不受支持、不安全或已弃用的客户端技术,例如 NSAPI 插件、Flash、Shockwave、ActiveX、Silverlight、NACL 或客户端 Java 小程序。
验证用户设置的密码长度至少为12个字符(合并多个空格后)。(C6)
验证是否允许至少64个字符的密码,以及是否拒绝超过128个字符的密码。(C6)
确认密码未被截断。但是,连续的多个空格可能会被替换为一个空格。(C6)
验证密码中允许使用任何可打印的 Unicode 字符,包括空格和表情符号等语言中性字符。
验证用户能否更改他们的密码。
验证密码更改功能是否需要用户的当前密码和新密码。
验证在账户注册、登录和密码更改过程中提交的密码是否与一组已泄露的密码进行核对,可以在本地进行(例如与系统密码策略匹配的前1000或10000个最常用密码)或使用外部API进行核对。如果使用 API,应使用零知识证明或其他机制以确保明文密码不会被发送或用于验证密码是否被泄露。如果密码已被泄露,应用程序必须要求用户设置一个新的未泄露密码。(C6)
确认提供密码强度测量工具,以帮助用户设置更强的密码。
验证是否没有限制允许字符类型的密码组成规则。密码不应要求包含大写或小写字母、数字或特殊字符。(C6)
确认没有定期凭证轮换或密码历史记录要求。
确认允许使用“粘贴”功能、浏览器密码助手和外部密码管理器。
确认用户能够选择临时查看整个被掩码的密码,或者在不具备此内置功能的平台上临时查看密码的最后一个输入字符。
验证防自动化控制是否能有效减轻凭证被泄露测试、暴力破解和账户锁定攻击。这些控制措施包括阻止最常被攻破的密码、软锁定、速率限制、验证码、尝试之间持续增加的延迟、IP地址限制,或基于风险的限制,例如位置、设备上的首次登录、近期解锁账户的尝试或类似情况。请验证单个账户每小时的失败尝试次数不超过100次。
验证弱验证方法(如短信和电子邮件)的使用是否仅限于二次验证和交易批准,而不是作为更安全验证方法的替代。验证在使用弱方法之前是否提供了更强的验证方法,用户是否意识到风险,或者是否已采取适当措施来限制账户被入侵的风险。
验证在更新认证信息后(如凭证重置、邮箱或地址更改、从未知或有风险的位置登录)是否向用户发送安全通知。优先使用推送通知而非短信或电子邮件,但在没有推送通知的情况下,短信或电子邮件也是可以接受的,只要通知中不泄露敏感信息。
验证防止网络钓鱼的冒充抵抗措施,例如使用多因素认证、带有意图的加密设备(如带有按压认证功能的连接密钥),或在更高的AAL级别使用客户端证书。
验证在凭证服务提供商(CSP)与验证身份的应用程序分离的情况下,两端点之间是否已建立相互认证的 TLS。
通过强制使用一次性密码(OTP)设备、加密认证器或查询代码来验证重放抵抗能力。
通过要求输入一次性密码(OTP)令牌或用户发起的操作(例如按下 FIDO 硬件钥匙上的按钮)来验证身份认证意图。
验证系统生成的初始密码或激活码应当是安全随机生成的,应至少包含6个字符,并且可以包含字母和数字,且应在短时间后失效。这些初始凭证不得作为长期密码使用。
验证是否支持用户提供的身份验证设备的注册和使用,例如 U2F 或 FIDO 令牌。
确认续订说明已提前发送,以便更新有时间限制的身份验证器。
验证密码是否以能够抵抗离线攻击的形式存储。密码必须使用批准的单向密钥派生或密码哈希函数进行加盐和哈希。密钥派生和密码哈希函数在生成密码哈希时以密码、盐和成本因子作为输入。(C6)
确认盐值长度至少为32位,并应任意选择以最小化存储的哈希值之间的盐值冲突。对于每个凭证,应存储唯一的盐值及其生成的哈希值。(C6)
请确保如果使用 PBKDF2,则迭代次数应尽可能大,在验证服务器性能允许的范围内,通常至少为 100,000 次迭代。(C6)
验证如果使用 bcrypt,工作因子应尽可能大,以匹配验证服务器的性能,最小值为 10。(C6)
验证是否执行了密钥派生函数的额外迭代,使用仅验证者知道的秘密盐值。使用经批准的随机比特生成器 [SP 800-90Ar1] 生成盐值,并提供至少符合 SP 800-131A 最新版本规定的最小安全强度。秘密盐值应与哈希密码分开存储(例如,在像硬件安全模块这样的专用设备中)。
验证系统生成的初始激活或恢复密钥未以明文形式发送给用户。(C6)
确认密码提示或基于知识的身份验证(所谓的“密保问题”)不存在。
验证密码凭证恢复不会以任何方式泄露当前密码。 (C6)
验证共享或默认账户不存在(例如“root”、“admin”或“sa”)。
确认如果身份验证因素被更改或替换,用户会收到此事件的通知。
验证忘记的密码以及其他恢复途径时,应使用安全的恢复机制,例如基于时间的一次性密码(TOTP)或其他软令牌、移动推送或其他离线恢复机制。(C6)
确认如果OTP或多因素身份验证因素丢失,身份验证的证据应与注册时的级别相同。
验证查找密钥只能使用一次。
验证查找密钥是否具有足够的随机性(112位熵),如果熵不足112位,则使用唯一且随机的32位盐进行加盐,并使用批准的单向哈希进行哈希。
验证查找密钥能够抵御离线攻击,例如可预测值的攻击。
验证默认情况下不提供基于明文的带外(NIST“受限制”)认证方式,例如短信或公用交换电话网(PSTN),并且首先提供更强的替代方案,例如推送通知。
验证带外验证器会在 10 分钟后使带外身份验证请求、代码或令牌失效。
验证带外验证器的身份验证请求、代码或令牌仅可使用一次,并且仅适用于原始身份验证请求。
验证带外身份验证器和验证器是否通过安全的独立通道进行通信。
验证带外验证器只保留身份验证码的哈希版本。
验证初始认证码是否由安全的随机数生成器生成,至少包含20位熵(通常六位数字的随机数就足够)。
验证基于时间的一次性密码在过期之前是否有定义的有效期。
验证用于验证提交的 OTP 的对称密钥是否得到高度保护,例如通过使用硬件安全模块或基于安全操作系统的密钥存储。
验证在 OTP 的生成、初始化和验证过程中使用的是经过批准的加密算法。
验证基于时间的一次性密码在有效期内只能使用一次。
验证如果在有效期内重复使用基于时间的多因素一次性密码(OTP)令牌,是否会被记录并拒绝,同时向设备持有者发送安全通知。
验证实体单因素 OTP 生成器在被盗或丢失的情况下可以被撤销。确保撤销在所有登录会话中立即生效,无论位置如何。
确保生物识别身份验证器仅限于作为二级因素使用,并需与您拥有的东西或您知道的东西结合使用。
验证用于验证的加密密钥是否安全存储并受到防泄露保护,例如使用可信平台模块(TPM)或硬件安全模块(HSM),或使用可以利用此安全存储的操作系统服务。
验证挑战随机数至少为64位长度,并且在统计上是唯一的,或在加密设备的使用寿命内是唯一的。
验证在生成、初始化和验证过程中使用了经过批准的密码算法。
确保服务内部的秘密不依赖于不变的凭证,例如密码、API 密钥或具有特权访问权限的共享账户。
请确保如果服务身份验证需要密码,所使用的服务账户不是默认凭据。(例如,在某些服务安装期间,root/root 或 admin/admin 是默认账户)。
验证密码是否以足够的保护方式存储,以防止离线恢复攻击,包括本地系统访问。
验证密码、与数据库和第三方系统的集成、种子和内部密钥,以及 API 密钥是否安全管理,并且不包含在源代码中或存储在源代码仓库中。这类存储应能够抵御离线攻击。建议使用安全的软件密钥存储(L1)、硬件 TPM 或 HSM(L3)来存储密码。
确保应用程序绝不在 URL 参数中泄露会话令牌。
验证应用在用户身份验证时是否生成新的会话令牌。(C6)
验证会话令牌是否至少具有 64 位熵。(C6)
验证应用程序仅使用安全方法在浏览器中存储会话令牌,例如适当安全的 Cookie(见第 3.4 节)或 HTML5 会话存储。
验证会话令牌是否使用批准的加密算法生成。(C6)
验证注销和会话过期是否使会话令牌失效,以确保浏览器的后退按钮或下游依赖方不会恢复已认证的会话,包括跨依赖方的情况。(C6)
如果身份验证器允许用户保持登录状态,请验证在用户主动使用或闲置一段时间后,是否会定期进行重新认证。(C6)
验证应用程序在密码成功更改后(包括通过密码重置/恢复更改时)是否提供终止所有其他活动会话的选项,并确保该选项在整个应用程序、联合登录(如果存在)以及任何依赖方中都有效。
验证用户是否能够查看并(在重新输入登录凭据后)注销任何或所有当前活跃的会话和设备。
验证基于 Cookie 的会话令牌是否设置了“Secure”属性。(C6)
验证基于 Cookie 的会话令牌是否设置了 'HttpOnly' 属性。(C6)
验证基于 Cookie 的会话令牌是否使用 “SameSite” 属性来限制跨站请求伪造攻击的风险。 (C6)
验证基于 Cookie 的会话令牌是否使用 "__Host-" 前缀,以便 Cookie 仅发送到最初设置该 Cookie 的主机。
确认如果应用程序是在与其他应用程序共享的域名下发布,而这些应用程序设置或使用可能泄露会话Cookie的Cookie,则应在基于Cookie的会话令牌中使用尽可能精确的路径设置路径属性。(C6)
验证应用程序是否允许用户撤销与关联应用程序建立信任关系的 OAuth 令牌。
验证应用程序使用会话令牌而非静态 API 密钥和密匙,除非是旧版本实现。
验证无状态会话令牌是否使用数字签名、加密以及其他对策来防护篡改、封装、重放、空密码和密钥替换攻击。
验证依赖方(RPs)是否向凭证服务提供商(CSPs)指定了最长认证时间,以及如果 CSP 在该时间段内未使用会话,是否会重新认证用户。
验证凭证服务提供商(CSP)是否向依赖方(RP)告知上一次的身份验证事件,以便依赖方确定是否需要重新对用户进行身份验证。
验证应用程序是否确保完整、有效的登录会话,或在允许任何敏感交易或账户修改之前要求重新认证或二次验证。
验证应用程序是否在可信服务层上强制执行访问控制规则,特别是在存在客户端访问控制且可能被绕过的情况下。
验证访问控制使用的所有用户和数据属性以及策略信息,除非有明确授权,否则不能被终端用户操纵。
验证最小权限原则是否存在——用户只能访问其具有特定授权的功能、数据文件、URL、控制器、服务和其他资源。这意味着要防护欺骗和权限提升。 (C7)
[已删除,重复 4.1.3]
验证访问控制在出现异常时也能安全失败。(C10)
验证敏感数据和 API 是否受到针对记录的创建、读取、更新和删除的不安全直接对象引用 (IDOR) 攻击的保护,例如创建或更新他人的记录、查看所有人的记录或删除所有记录。
验证应用程序或框架是否实施了强大的反CSRF机制以保护已认证的功能,并且有效的反自动化或反CSRF机制能够保护未认证的功能。
验证管理界面是否使用适当的多因素身份验证以防止未经授权的使用。
确保目录浏览已被禁用,除非是有意为之。此外,应用程序不应允许发现或泄露文件或目录的元数据,例如 Thumbs.db、.DS_Store、.git 或 .svn 文件夹。
确认应用程序对于低价值系统具有额外的授权(例如升级认证或自适应认证),并且/或者对高价值应用程序实施职责分离,以根据应用程序的风险和以往的欺诈情况执行反欺诈控制。
验证应用程序是否具备防御 HTTP 参数污染攻击的能力,尤其是在应用程序框架对请求参数的来源(GET、POST、cookie、头部或环境变量)不加区分时。
确认框架能防止批量参数分配攻击,或者应用程序有相应的防护措施来防止不安全的参数分配,例如将字段标记为私有或采取类似措施。(C5)
验证所有输入(HTML 表单字段、REST 请求、URL 参数、HTTP 头、Cookie、批处理文件、RSS 源等)是否使用正向验证(允许列表)进行验证。(C5)
验证结构化数据是否为强类型,并根据定义的模式进行验证,包括允许的字符、长度和模式(例如信用卡号码、电子邮件地址、电话号码,或验证两个相关字段是否合理,例如检查郊区和邮政编码是否匹配)。(C5)
验证 URL 重定向和转发仅允许出现在允许列表中的目标,或在重定向到潜在不受信任的内容时显示警告。
确认来自所见即所得编辑器或类似工具的所有不受信任的 HTML 输入已通过 HTML 消毒库或框架功能正确消毒。(C5)
验证非结构化数据已被清理,以执行安全措施,例如允许的字符和长度。
验证应用程序在将用户输入传递给邮件系统之前是否进行了清理,以防止 SMTP 或 IMAP 注入。
确保应用程序避免使用 eval() 或其他动态代码执行功能。如果没有替代方案,任何包含的用户输入必须在执行前进行清理或沙箱处理。
通过确保任何被包含的用户输入都经过清理或沙箱处理,来验证应用程序防护模板注入攻击的能力。
验证应用程序是否能够防护 SSRF 攻击,通过验证或清理不可信的数据或 HTTP 文件元数据,如文件名和 URL 输入字段,并使用协议、域名、路径和端口的允许列表。
验证应用程序是否对用户提供的可缩放矢量图形(SVG)可脚本内容进行清理、禁用或沙箱处理,特别是与由内联脚本和 foreignObject 引起的跨站脚本(XSS)相关的内容。
验证应用程序是否对用户提供的可脚本或表达式模板语言内容(如 Markdown、CSS 或 XSL 样式表、BBCode 或类似内容)进行清理、禁用或沙箱处理。
验证输出编码是否与解释器和所需上下文相关。例如,根据上下文需要,使用专门用于 HTML 值、HTML 属性、JavaScript、URL 参数、HTTP 头、SMTP 等的编码器,特别是针对不可信输入(例如包含 Unicode 或撇号的名称,如 ねこ 或 O'Hara)。(C4)
验证输出编码是否保留用户选择的字符集和区域设置,以确保任何 Unicode 字符点都是有效且安全处理的。(C4)
验证上下文感知的输出转义(最好是自动的,最坏情况下是手动的)是否能防护反射型、存储型和基于 DOM 的 XSS。(C4)
验证数据选择或数据库查询(例如 SQL、HQL、ORM、NoSQL)是否使用参数化查询、ORM、实体框架,或以其他方式防止数据库注入攻击。(C3)
确认在没有使用参数化或更安全的机制时,采用了特定上下文的输出编码来防止注入攻击,例如使用 SQL 转义来防止 SQL 注入。(C3, C4)
验证应用程序是否能够防护 JSON 注入攻击、JSON eval 攻击以及 JavaScript 表达式求值攻击。(C4)
验证应用程序是否能防护LDAP注入漏洞,或者是否已经实施了防止LDAP注入的特定安全控制措施。(C4)
验证应用程序是否能防止操作系统命令注入,并确保操作系统调用使用参数化的 OS 查询或使用上下文命令行输出编码。(C4)
验证应用程序是否能够防护本地文件包含(LFI)或远程文件包含(RFI)攻击。
验证应用程序是否能够防止 XPath 注入或 XML 注入攻击。(C4)
验证应用程序是否使用内存安全的字符串、更安全的内存拷贝和指针运算来检测或防止栈、缓冲区或堆溢出。
确保格式字符串不会接收可能具有敌意的输入,并且是常量。
验证是否使用了符号、范围和输入验证技术来防止整数溢出。
验证序列化对象是否使用完整性检查或加密,以防止恶意对象创建或数据篡改。(C5)
验证应用程序是否正确限制 XML 解析器仅使用最严格的配置,并确保禁用解析外部实体等不安全功能,以防止 XML 外部实体(XXE)攻击。
验证在自定义代码和第三方库(如 JSON、XML 和 YAML 解析器)中是否避免对不可信数据进行反序列化,或对其进行保护。
请确保在浏览器或基于JavaScript的后端解析JSON时,使用JSON.parse来解析JSON文档。不要使用eval()来解析JSON。
确保受监管的私密数据在静态存储时是加密的,例如个人身份信息(PII)、敏感个人信息或被评估可能受欧盟《通用数据保护条例》(GDPR)约束的数据。
验证受监管的健康数据在静止状态下是否以加密形式存储,例如病历、医疗设备详细信息或去标识化的研究记录。
验证受监管的财务数据在静态存储时是否已加密,例如财务账户、违约或信用记录、税务记录、工资历史、受益人信息,或去匿名化的市场或研究记录。
验证所有加密模块在失败时能安全处理,并且错误的处理方式不会导致填充预言攻击。
验证是否使用经过行业验证或政府批准的加密算法、模式和库,而不是自定义编码的加密。(C8)
验证加密初始化向量、密码配置和分组模式是否根据最新建议进行安全配置。
验证随机数、加密或哈希算法、密钥长度、轮数、密码或模式是否可以随时重新配置、升级或替换,以防止密码学破解。(C8)
确保未使用已知不安全的区块模式(如 ECB 等)、填充模式(如 PKCS#1 v1.5 等)、小区块加密算法(如 Triple-DES、Blowfish 等)以及弱哈希算法(如 MD5、SHA1 等),除非为向后兼容而必须使用。
验证随机数、初始化向量以及其他一次性使用的数字在使用给定加密密钥时不得重复使用。生成方法必须适合所使用的算法。
通过签名、经过认证的密码模式或 HMAC 验证加密数据的真实性,以确保密文未被未经授权的方篡改。
确保所有加密操作都是恒定时间的,在比较、计算或返回中没有“短路”操作,以避免信息泄露。
当这些随机值旨在不被攻击者猜测时,验证所有随机数、随机文件名、随机 GUID 和随机字符串是否使用加密模块批准的加密安全随机数生成器生成。
验证随机 GUID 是否使用 GUID v4 算法和加密安全的伪随机数生成器(CSPRNG)创建。使用其他伪随机数生成器创建的 GUID 可能是可预测的。
验证即使在应用程序负载较大时,随机数也能以适当的熵生成,或者应用程序在这种情况下能够平稳降级。
验证是否使用诸如密钥库等机密管理解决方案来安全地创建、存储、控制访问和销毁机密信息。(C8)
验证密钥材料未暴露给应用程序,而是使用像保险库这样的隔离安全模块进行加密操作。(C8)
验证应用程序是否未记录凭据或支付信息。会话令牌应仅以不可逆的哈希形式存储在日志中。(C9, C10)
验证应用程序是否未记录根据当地隐私法或相关安全策略定义的其他敏感数据。(C9)
验证应用程序是否记录与安全相关的事件,包括成功和失败的身份验证事件、访问控制失败、反序列化失败和输入验证失败。(C5, C7)
验证每个日志事件是否包含必要的信息,以便在事件发生时能够对时间线进行详细调查。(C9)
确保所有身份验证决策都被记录,但不要存储敏感的会话令牌或密码。这应包括包含安全调查所需相关元数据的请求。
验证所有访问控制决策都可以被记录,并且所有失败的决策都已记录。这应包括安全调查所需的相关元数据请求。
验证所有日志组件是否适当编码数据以防止日志注入。(C9)
[已删除,7.3.1 重复]
验证安全日志是否受保护,防止未经授权的访问和修改。 (C9)
确保时间源与正确的时间和时区同步。如果系统是全球性的,强烈建议仅以 UTC 记录日志,以便事后进行事件取证分析。(C9)
验证当发生意外或安全敏感错误时,是否显示通用消息,可能带有支持人员可用来调查的唯一 ID。(C10)
验证在整个代码库中是否使用了异常处理(或功能等效方法)来处理预期和意外的错误情况。(C10)
验证是否定义了“最后手段”错误处理程序,该程序将捕获所有未处理的异常。(C10)
验证应用程序是否防止敏感数据被缓存到服务器组件中,例如负载均衡器和应用缓存。
确保服务器上存储的所有敏感数据的缓存或临时副本在未经授权访问时受到保护,或者在授权用户访问敏感数据后被清除/作废。
验证应用程序是否尽量减少请求中的参数数量,例如隐藏字段、Ajax变量、Cookie和头部值。
验证应用程序是否能够检测并提醒异常数量的请求,例如按IP、用户、每小时或每天的总数,或任何对应用程序有意义的方式。
确认重要数据进行了定期备份,并进行了数据恢复测试。
确保备份安全存储,以防数据被盗或损坏。
验证应用程序是否设置了足够的防缓存头,以确保敏感数据不会被现代浏览器缓存。
验证存储在浏览器存储(如 localStorage、sessionStorage、IndexedDB 或 cookies)中的数据不包含敏感信息。
验证在客户端或会话终止后,经过身份验证的数据是否已从客户端存储中清除,例如浏览器 DOM。
验证敏感数据是否在 HTTP 消息体或头部发送到服务器,并确保任何 HTTP 方法的查询字符串参数不包含敏感数据。
确保用户有方法根据需要删除或导出他们的数据。
请确保向用户提供关于收集和使用所提供个人信息的清晰说明,并且在以任何方式使用这些数据之前,用户已提供同意使用这些数据的选择加入许可。
验证应用程序创建和处理的所有敏感数据是否已被识别,并确保有关于如何处理敏感数据的政策已制定。(C8)
验证访问敏感数据是否被审计(不记录敏感数据本身),如果数据是在相关数据保护指令下收集的,或在需要记录访问的情况下。
在不再需要敏感信息时,验证内存中的敏感信息已被覆盖,以减轻内存转储攻击的风险,可使用零或随机数据进行覆盖。
验证需要加密的敏感或私人信息是否使用经过批准的算法进行加密,这些算法能同时提供机密性和完整性。(C8)
确保敏感个人信息受到数据保留分类的管理,以便过时或不再需要的数据能够自动、按计划或根据情况删除。
验证所有客户端连接是否使用 TLS,并且不会回退到不安全或未加密的通信。(C8)
使用最新的 TLS 测试工具验证仅启用强加密套件,并将最强的加密套件设置为首选。
验证仅启用 TLS 协议的最新推荐版本,如 TLS 1.2 和 TLS 1.3。TLS 协议的最新版本应作为首选选项。
验证与服务器的连接是否使用受信任的 TLS 证书。如果使用内部生成或自签名证书,必须将服务器配置为仅信任特定的内部 CA 和特定的自签名证书。其他所有证书都应被拒绝。
验证所有入站和出站连接(包括管理端口、监控、身份验证、API 或 Web 服务调用、数据库、云、无服务器、主机、外部和合作伙伴连接)是否使用加密通信,如 TLS。服务器不得回退到不安全或未加密的协议。
验证所有涉及敏感信息或功能的外部系统加密连接是否经过身份验证。
验证已启用并配置了适当的证书撤销,例如在线证书状态协议(OCSP)订书针。
验证后台TLS连接失败是否已被记录。
确认正在使用的代码分析工具能够检测潜在的恶意代码,例如时间函数、不安全的文件操作和网络连接。
验证应用程序源代码和第三方库是否不包含未经授权的回传或数据收集功能。如果存在此类功能,请在收集任何数据之前获取用户的许可。
验证应用程序是否不会请求与隐私相关的功能或传感器(如联系人、相机、麦克风或位置)无关的或过多的权限。
验证应用程序源代码和第三方库中是否不包含后门,例如硬编码或额外的未记录账户或密钥、代码混淆、未记录的二进制模块、Rootkit 或反调试功能、不安全的调试功能,或其他过时、不安全或隐藏的功能,如果被发现可能会被恶意利用。
通过搜索与日期和时间相关的函数,验证应用程序源代码和第三方库中不包含定时炸弹。
验证应用程序源代码和第三方库中是否不包含恶意代码,例如切片攻击、逻辑绕过或逻辑炸弹。
验证应用程序的源代码和第三方库是否不包含彩蛋或其他任何潜在的不良功能。
确保如果应用程序具有客户端或服务器自动更新功能,更新应通过安全通道获取并进行数字签名。更新代码在安装或执行更新之前必须验证更新的数字签名。
验证应用程序是否采用了完整性保护措施,例如代码签名或子资源完整性。应用程序不得从不受信任的来源加载或执行代码,例如从不受信任的来源或互联网加载包含文件、模块、插件、代码或库。
如果应用程序依赖于 DNS 条目或 DNS 子域(例如过期的域名、过时的 DNS 指针或 CNAME、公共源代码仓库中的过期项目,或临时的云 API、无服务器函数或存储桶(*autogen-bucket-id*.cloud.example.com)等),请验证该应用程序是否具备防止子域接管的保护。保护措施可以包括确保应用程序使用的 DNS 名称定期检查是否过期或发生变化。
验证应用程序是否仅按顺序处理同一用户的业务逻辑流程,且不跳过任何步骤。
验证应用程序只会处理所有步骤都在现实人类时间内完成的业务逻辑流程,即交易提交不会过快。
验证应用程序对特定业务操作或交易是否具有适当的限制,并且这些限制是否按每个用户正确执行。
验证应用程序是否具有反自动化控制,以防止过度调用,例如大规模数据外泄、业务逻辑请求、文件上传或拒绝服务攻击。
验证应用程序是否具有业务逻辑限制或验证,以防护可能的业务风险或威胁,这些风险或威胁是通过威胁建模或类似方法识别的。
验证应用程序在敏感操作中不会出现“检查时与使用时” (TOCTOU) 问题或其他竞争条件。
验证应用程序是否从业务逻辑角度监控异常事件或活动。例如,尝试执行不按顺序的操作或正常用户绝不会尝试的操作。(C9)
验证应用程序在检测到自动化攻击或异常活动时是否具有可配置的警报功能。
验证应用程序不会接受可能占满存储或导致拒绝服务的大文件。
验证应用程序在解压文件之前是否会检查压缩文件(例如 zip、gz、docx、odt)的最大允许解压后大小以及最大文件数量。
验证是否实施了文件大小配额和每个用户的最大文件数量限制,以确保单个用户无法通过过多文件或过大文件占满存储空间。
验证从不可信来源获取的文件是否根据文件内容被确认为预期类型。
验证用户提交的文件名元数据未被系统或框架文件系统直接使用,并确保使用 URL API 来防止路径遍历。
验证用户提交的文件名元数据是否经过验证或被忽略,以防止本地文件(LFI)的泄露、创建、更新或删除。
验证用户提交的文件名元数据是否经过验证或被忽略,以防止通过远程文件包含(RFI)或服务器端请求伪造(SSRF)攻击泄露或执行远程文件。
验证应用程序通过对 JSON、JSONP 或 URL 参数中用户提交的文件名进行验证或忽略,以防止反射性文件下载(RFD),响应的 Content-Type 头应设置为 text/plain,并且 Content-Disposition 头应具有固定的文件名。
验证不可信的文件元数据是否未被直接用于系统 API 或库,以防 OS 命令注入。
确认应用程序不包含并执行来自不可信源的功能,例如未经验证的内容分发网络、JavaScript 库、Node npm 库或服务器端 DLL。
确保从不可信来源获得的文件存储在 Web 根目录之外,并且权限有限。
确保来自不受信任来源的文件经过杀毒软件扫描,以防止上传和提供已知的恶意内容。
验证 Web 层是否配置为仅提供具有特定文件扩展名的文件,以防止无意的信息和源代码泄露。例如,除非必要,否则应屏蔽备份文件(如 .bak)、临时工作文件(如 .swp)、压缩文件(例如 .zip、.tar.gz 等)以及其他编辑器常用的扩展名。
确保对已上传文件的直接请求永远不会作为 HTML/JavaScript 内容执行。
验证网页或应用服务器是否配置了允许列表,指定服务器可以发送请求或从中加载数据/文件的资源或系统。
请确保所有应用程序组件使用相同的编码和解析器,以避免利用不同 URI 或文件解析行为的解析攻击,这类攻击可能被用于 SSRF 和 RFI 攻击。
[已删除,重复 4.3.1]
验证 API URL 不会暴露敏感信息,例如 API 密钥、会话令牌等。
确认授权决策在 URI 层面(由控制器或路由器通过编程或声明式安全执行)和资源层面(由基于模型的权限执行)都已做出。
验证包含意外或缺失内容类型的请求是否被拒绝,并返回适当的头信息(HTTP 响应状态 406 不可接受或 415 不支持的媒体类型)。
验证启用的 RESTful HTTP 方法是否对用户或操作是有效的选择,例如防止普通用户在受保护的 API 或资源上使用 DELETE 或 PUT。
在接受输入之前,确保已启用并验证 JSON 模式验证。
验证使用 Cookie 的 RESTful 网络服务是否通过以下一种或多种方式防止跨站请求伪造 (CSRF):双重提交 Cookie 模式、CSRF 随机数(nonce)或 Origin 请求头检查。
[已删除,重复 11.1.4]
验证 REST 服务是否明确检查传入的 Content-Type 是否为预期类型,例如 application/xml 或 application/json。
验证消息头和有效负载是否可信,并且在传输过程中未被修改。在许多情况下,要求传输使用强加密(仅限 TLS)可能就足够了,因为它同时提供机密性和完整性保护。每条消息的数字签名可以在传输保护的基础上为高安全性应用提供额外的保障,但同时也带来了额外的复杂性和风险,需要权衡其益处。
验证 XSD 模式以确保 XML 文档格式正确,然后在处理任何数据之前验证每个输入字段。
验证消息负载是否使用 WS-Security 签名,以确保客户端与服务之间的传输可靠。
请验证是否使用了查询允许列表或深度限制与数量限制相结合的方法,以防止由于昂贵的嵌套查询导致的 GraphQL 或数据层表达式拒绝服务(DoS)。对于更高级的场景,应使用查询成本分析。
请确认 GraphQL 或其他数据层的授权逻辑应在业务逻辑层实现,而不是在 GraphQL 层实现。
确保应用程序的构建和部署过程以安全且可重复的方式进行,例如使用 CI/CD 自动化、自动化配置管理和自动化部署脚本。
验证编译器标志是否已配置为启用所有可用的缓冲区溢出保护和警告,包括堆栈随机化、数据执行防护,以及在发现不安全的指针、内存、格式字符串、整数或字符串操作时中断构建。
验证服务器配置是否已根据所使用的应用服务器和框架的建议进行加固。
验证应用程序、配置和所有依赖项是否可以使用自动部署脚本重新部署,这些脚本应基于有文档记录且经过测试的操作手册,并在合理时间内完成,或能够从备份中及时恢复。
验证授权管理员是否能够验证所有与安全相关的配置的完整性,以检测篡改。
验证所有组件是否是最新的,最好在构建或编译时使用依赖检查工具。 (C2)
确认已移除所有不需要的功能、文档、示例应用和配置。
验证如果应用程序资源(如 JavaScript 库、CSS 或网页字体)托管在内容分发网络 (CDN) 或外部提供商处,是否使用子资源完整性 (SRI) 来验证资源的完整性。
验证第三方组件来自预定义的、可信的且持续维护的存储库。(C2)
确保维护所有使用中的第三方库的软件材料清单(SBOM)。(C2)
通过对第三方库进行沙箱化或封装,仅将所需的行为暴露给应用程序,以验证攻击面是否已减少。(C2)
[已删除,7.4.1 的重复项]
确认在生产环境中禁用网页或应用服务器以及应用框架的调试模式,以消除调试功能、开发者控制台和意外的安全信息泄露。
验证 HTTP 头或 HTTP 响应的任何部分是否不会泄露系统组件的详细版本信息。
验证每个 HTTP 响应是否包含 Content-Type 头。如果内容类型是 text/*、*/xml 或 application/xml,还应指定一个安全的字符集(例如 UTF-8、ISO-8859-1)。内容必须与提供的 Content-Type 头匹配。
验证所有 API 响应是否包含 Content-Disposition: attachment; filename="api.json" 头(或其他适合内容类型的文件名)。
验证是否存在能够帮助减轻 HTML、DOM、JSON 和 JavaScript 注入漏洞等 XSS 攻击影响的内容安全策略(CSP)响应头。
确认所有响应都包含 X-Content-Type-Options: nosniff 头。
验证是否在所有响应和所有子域上都包含 Strict-Transport-Security 头,例如 Strict-Transport-Security: max-age=15724800; includeSubdomains。
验证是否包含合适的 Referrer-Policy 头,以避免通过 Referer 头向不可信方暴露 URL 中的敏感信息。
验证默认情况下网页应用的内容不能被嵌入第三方网站,并且仅在必要时使用适当的 Content-Security-Policy: frame-ancestors 和 X-Frame-Options 响应头允许嵌入相同的资源。
验证应用服务器仅接受应用程序/API 使用的 HTTP 方法,包括预检 OPTIONS,并记录/报警任何对应用程序上下文无效的请求。
确认提供的 Origin 头未被用于身份验证或访问控制决策,因为 Origin 头很容易被攻击者篡改。
验证跨源资源共享(CORS)Access-Control-Allow-Origin 头是否使用严格的允许列表来匹配受信任的域名和子域名,并且不支持“null”来源。
验证由可信代理或 SSO 设备添加的 HTTP 头,例如承载令牌,是否已被应用程序认证。