Java 作为顶级编程语言之一,已经在企业级软件开发领域活跃 25 年了。有人不断宣传 Java 已死,同时也有人坚称 Java 活得好好的。最近,又有报道称 log4j2 漏洞将再次“杀死” Java。我们曾开玩笑说,Java博物馆就好像是一个墓园,记录了每一次“死亡”的经过。

作者:Erik Costlow 译者:弯月
链接:https://foojay.io/today/log4j-isnt-killing-java/

上周,技术圈被 log4j2 漏洞掀起巨浪,各大安全公司纷纷发文介绍该漏洞的危害,并给出了各种临时解决方案。还有一些博主也发表文章教我们如何找到易受攻击的地方,并采取相应的防御措施。还有大量帖子跟着起哄,讨论如何采用一些不必要的防御技术。

目前,log4j2 官方团队已发布 2.16.0 新版本,加固漏洞防御机制。log4j2 是一款基于 Java 研发的开源日志系统,因此,当史诗级漏洞被爆出后,便有人宣称 log4j2 漏洞将再次“杀死” Java,已经被“死亡”过无数次的 Java,就像是开了一个墓园,记录每次“死亡”经过。

本文将简单介绍一下 Java 生态系统,说明什么是日志记录框架、在何处使用以及使用的原因,此外,还将介绍各个团队应当如何观察和控制 JVM 的行为。

Java 开发人员应该做哪些安全工作

快速给 JDK 和库打补丁是当前最有效的技术,可避免绝大多数大规模的黑客攻击。

给库文件打补丁(必需)

当代码库中存在漏洞时,最有效的技术就是打补丁以去除漏洞。如果不给库文件打补丁,那么应用程序很有可能被黑客入侵,攻击者将获得系统及其数据的完整访问权限。

无论在何种情况下,通常打补丁都很有效。

日志框架可能来自任何依赖项,可能由另一个库引入(即传递依赖项),而非由开发人员添加(即直接依赖项)。我们可以使用依赖项分析工具,例如 Contrast Community Edition,来检测依赖项和其他自定义的漏洞。

此外,还有一些分析依赖关系的开源工具,比如 Maven 依赖树(dependency:tree)和 Gradle 依赖树。NetBeans 等 IDE 也提供了依赖关系图可视化工具。

对于 log4j2 漏洞,你必须升级到 2.15.0 或更高版本。

给 JRE 打补丁,升级到 Java 的安全基线(推荐,定期执行)

每个Java 主要版本都会维护一个安全基线。由于每个季度 JDK 都会提供带有新安全改进的补丁,因此这个安全基线也会不断向前移动。低于安全基线的 Java 包含已知的安全问题,应该升级。

这是标准的安全最佳实践,与 log4j2 漏洞没有直接关系,也不会修复该漏洞。

各个团队可以使用 Foojay Disco API 自动监控安全基线,并及时地升级系统。开发人员可以将这个更新与 GitHub 操作相结合,确保在每次构建代码时,都使用最新的安全更新。如果发生安全事件,则立即升级 JRE,同时重新构建并重新部署代码。下面这个测试矩阵中就包含了这类的 GitHub 操作(https://github.com/foojayio/discoTestingMatrix)。

Java 安全基线的升级时间为:每年 1 月、4 月、7 月和 10 月,17 日前后的周二。详细信息包含在Oracle 重要补丁更新计划(https://www.oracle.com/security-alerts/)中,OpenJDK 漏洞组(https://foojay.io/pedia/security-vulnerability-management/)也采用了同一个计划。此外,如果出现重大问题,Oracle 还会提供计划外的安全更新。但 log4j2 漏洞不属于这种情况。

以下配置演示了如何使用 Java 11 的安全基线:

jobs:java11:runs-on: ${{ matrix.os }}strategy:matrix:os: [ubuntu-latest, macos-latest, windows-latest]update: [x]package: [jdk, jre]fail-fast: falsemax-parallel: 4name: ${{ matrix.package }} 11.0.${{ matrix.update }}, ${{ matrix.os }}steps:- uses: actions/checkout@v1- name: Set up JDK 11 Zuluuses: foojayio/setup-java@discowith:java-package: ${{ matrix.package }}java-version: 11.0.${{ matrix.update }}distro: zulu- name: java -versionrun: java -version

定期检测自定义安全漏洞(推荐测试采用)

自动化安全工具可以捕获安全漏洞,不需要安全专业知识。将这类安全工具集成到 Java 应用程序,就可以实现安全监测,并记录安全信息。有些工具会根据依赖项的数量来决定是否存在漏洞,而这种方法则会根据依赖信息,由集成的分析器来报告这些依赖库的组合情况,并判断组合后是否安全。

例如,集成分析器不只是简单地检查 log4j2 存在与否及其版本,而且还可以确定攻击者是否可以控制远程日志输入。

此外,Contrast Community Edition 之类的免费分析器还能够即时捕获 log4j2,并捕获许多其他的安全漏洞,例如:

  • 应用程序的 Hibernate、JBDC 或任何其他地方是否包含 SQL 注入问题?

  • 远程用户能否控制发送到 Runtime.exec 的任何输入,即是否存在命令注入漏洞?

  • 应用程序使用了哪些加密算法,在何处使用,是否符合适当的标准?

  • 开发人员在结合使用多个库时,是否意外引入了某个安全漏洞,例如 OGNL 输入解析?

  • 以及其他应用程序特有的安全漏洞。

使用 JDK Flight Recorder 监控安全事件

JDK Flight Recorder 是现代 OpenJDK 发行版中包含的性能分析工具,它不仅可以生成一些安全信息,而且开销非常低。各个团队可以使用 JDK Flight Recorder 来记录许多 IO 操作,例如 JRE 访问了哪些文件,或者哪些类会被反序列化。

通过使用 JDK Flight Recorder 监视 Java 应用程序事件,并通过数据流将事件传输到安全信息和事件管理(Security Information and Event Management,即SIEM)系统中,Java 团队就可以监视异常行为,并通过可防止漏洞的 Java 反序列化过滤器来检查各个类是否安全。

哪些安全措施没有太大作用

对于 log4j2 漏洞的问题,Web Application Firewall(WAF)之类基于网络的防御和工具可能在短期内有一定的效果,但通常都没有太大作用,而且工作量非常大。

  • 网络防御的效果不大。网上流传着一个梗,一张经过 PS 的汽车照片,其车牌号上包含了一条注入工具。这个梗的点就在于,开发人员都知道,车牌号会通过计算机视觉分析后记录到日志中。构成注入的数据并没有出现在网络层。同样,大多数应用程序使用数据的不同部分,解码数据并记录各种信息。任何网络工具都无法匹配足够多的模式来检测安全问题。

  • 通过观察和追踪来阻止攻击者 IP 的方法并不是特别有效。虽然有些团队可能会维护一张攻击者的列表,但 AWS IP 之所以被称为弹性 IP,是因为这些 IP 会定期变化,因此,即便你阻止了某个 IP,过一段时间可能就又解锁了,或者很快就会受到不同 IP 的攻击。

图:该图演示了网络层无法检测到的漏洞

系统属性和动态补丁的效果一般

有几个补丁和系统属性可以控制 log4j2 的行为并阻止攻击。有时候,有些库无法及时更新,或者团队在努力更新依赖项,但需要一定的时间,在这两种情况下,就可以考虑这几个补丁和系统属性。

相关的 Java 系统属性有两个:

  • -Dcom.sun.jndi.rmiobject.trustURLCodebase=false

  • -Dcom.sun.jndi.cosnaming.object.trustURLCodebase=false

将这两个属性设置为 false 可以阻止远程攻击。

还有一个动态的补丁,它可以连接到正在运行的 JVM 并给其打补丁。这个补丁必须在 JVM 每次启动时应用。虽然这两种方法有一定的作用,但相较而言,更新库更简单。

Java 如何处理日志

Java 开发人员一般可以从多个日志系统和记录方式中进行选择。多年来,随着社区的发展,许多日志框架也可以协同工作了:

  • System Logger(2017 年推出,推荐)是 JDK 9 中引入的日志系统。它改进了 JDK Logger 的 API,并提供了类似于 SLF4j 的记录方式,可以将 JDK 的日志重定向到应用程序团队选择的日志系统。

  • JDK Logger(2004 年推出)是 Java 1.4 中引入的日志系统。由于 JDK 中大量使用了该日志系统,因此变得很流行,但是 API 有点蹩脚。虽然这个日志系统也不错,但不如其他框架。

  • Log4j 和 Log4j2 是社区推荐的日志系统,二者改进了 API,因此开发团队可以更轻松地控制记录的内容以及各个级别的日志记录数据的方式。

  • Logback 和 SLF4j 也是流行的日志系统。SLF4J 是一个简单的日志记录方式,可帮助团队处理许多日志记录,库的维护人员可以将日志输出到 SLF4J,然后由应用程序开发人员配置他们将使用哪些底层的日志系统来统一输出。此外 SLF4J 还建立了良好的 API,最大限度地减少了依赖关系。

  • JBoss Logger 是 JBoss 生态系统中的另一个流行的日志系统。该系统性能良好,而且运行速度很快。如今它还支持其他流行框架,如 Quarkus。

  • Apache Commons-Logging(2002 年推出)诞生于 JDK 日志系统之前,并启发了许多 API。它的最后一个版本是于 2014 年推出的,之后人们陆续开始采用其他以支持良好的日志记录为目标的 API。

2022年推荐的日志系统

依赖项越少越好,项目越新越好,因此我们可以考虑 System Logger。

有些项目拥有大量依赖项,但优势在于它们使用的日志记录工具与大多数的依赖项相同,只不过选用了其他日志记录方式。

如果你没有任何日志系统,则可以考虑 System Logger,它是一款拥有良好 API 的 JDK 日志记录工具。

日志系统到底是做什么的?

日志框架能够让应用程序的主人看到通用格式的日志消息、时间戳、线程名称以及其他数据。

此外,团队可以将不同的输出重定向到不同的位置,甚至无需显示出来,例如,你可以将访问日志发送到一个文件,将系统报告发送到其他地方,然后选择显示所有级别的日志信息,或者动态查看某个库的调试信息。

Log4j2 杀不死 Java相关推荐

  1. 如何让Java应用成为杀不死的小强?(中篇)

    [这是一猿小讲的第 48 篇原创分享] 各位坐稳扶好,我们要开车了.不过在开车之前,我们还是例行回顾一下上期分享的要点. 上期我们抛了一个砖:"如何实现 Java 应用进程的状态监控,如果被 ...

  2. app之 杀不死的进程

    有些需求要求app进程杀不死 我觉的扯再多都是没用的  不如 给你们看看~~~人家是如何实现的 demo是可以用的 我已经测试成功了 感觉很厉害哦~~好佩服的哦~~~哦哦哦~~~    常驻进程 An ...

  3. Android_常驻进程(杀不死的进程)

    Android常驻进程,就是要让进程在内存中永远存在,让进程保活,不被杀死.可能这时都会喷,这不是流氓软件吗?刚接触android的时候,我也是认为这是很流氓的做法,可是慢慢发现很多场景(应用),要为 ...

  4. Android中创建杀不死的APP进程(5.0以下)

    所谓的杀不死指的时进程被杀掉后,会自动重启. 即便时在设置里面强行停止后,也能够自动重启. 那么如何自动重启呢?目前想到的有3种方式: 1.使用AlarmManager来定时发intent启动 2.N ...

  5. 杀不死的人狼——我读《人月神话》(四)

    <<==上一节 ===== 四.没有银弹,或人狼杀不死 ===== 人狼这个动物很奇怪,皮肉坚实还是自疗系的,所以要么砍它不动,要么杀它不死.这种动物如同习得(传说中的)金钟罩功夫,刀枪不 ...

  6. 杀不死你的,终将使你更强大

    从4月份到10月底,开发的新功能顺利上线了,运行平稳.这期间除了忙,就是巨忙.除了8月初休假一周回了趟老家,其他时间每天从早拼到晚,周末时间也搭进去不少.但是总归结果是挺好的. 接下来新的任务挑战性更 ...

  7. 杀不死的人狼——我读《人月神话》(五)

    <<==上一节 ===== 五.从广义工程到狭义工程 ===== 现在我们回到一个实际的问题上:工程的本质需求是什么?如果我问一千个人工程的本质,可能会得到一千种答案.因为大家离本质的东西 ...

  8. centos7 杀不死 httpd (Apache )

    今天遇到一个问题,杀不死httpd (Apache ),杀死后,它又重开了一个进程,继续搞事情,一直占着我的80端口. 解决办法: 直接使用命令: pkill httpd ok ,这就杀死了. 前因后 ...

  9. Linux下kill -9杀不死进程或杀死又自动启动,解决

    问题描述 在ubuntu下 kill -9 杀死进程时候发现杀不死,或者是杀死了立刻又重启. 原因是该进程的父进程还在,所以会杀死进程后又自动启动了,看起来是我们没kill掉一样. 解决方法 ps - ...

最新文章

  1. 实验三:XML模型(二)
  2. CNN阴影去除--DeshadowNet: A Multi-context Embedding Deep Network for Shadow Removal
  3. 读书笔记-我所理解的生活
  4. C语言从0到1·源程序,源文件,目标文件之间的关系
  5. pandas数据处理 代码_使用Pandas方法链接提高代码可读性
  6. 单片机小白学步系列(十) 单片机程序下载相关知识
  7. PHP常用工具方法集...
  8. 汉诺塔(三) 判断操作是否合法 + 栈(stack)数组
  9. 深度学习下,中文分词是否还有必要?——ACL 2019论文阅读笔记
  10. DDoS 攻击次数和流量峰值情况
  11. java内存模型 infoq_深入理解 java 内存模型_程晓明_infoq.pdf
  12. 计算机保研er去清华计算法学怎么样?
  13. 爬虫爬取实时新闻标题、时间及新闻内容并保存
  14. odoo学习必看-提问的智慧《How To Ask Questions The Smart Way》
  15. 【蓝桥杯Python-无聊的逗】解题思路和参考代码
  16. 腾讯实习生面试2016两道面试题目?(知乎)
  17. 达观数据曾彦能:如何用深度学习做好长文本分类与法律文书智能化处理
  18. 服务端渲染SSR与客户端渲染
  19. axios+Vant+vue+jq重构jq月经周期计算器源代码(兼容移动端)
  20. uboot中利用TFTP和NFS加载内核镜像和根文件系统

热门文章

  1. 项目学习类容,日期处理,SQL语句查询,hashtable的运用,R语言包的环境配置
  2. Linux查看、运行和杀死java进程
  3. flex include和import
  4. SQL Server Express无法建立ODBC问题(错误代码67 和17)
  5. 关于笔算递归的通用算法——迭代
  6. sqlserver数据库 表中字段值有空格,如何去除空格(例如char (5) 存入数据不足5位时sqlserver会自动补空格)...
  7. Xcode7 Xcode6 中添加pch文件
  8. [Ubuntu] 16.04 卸载旧内核并禁止内核更新
  9. leetcode 559 N叉树的最大深度
  10. linux工程师如何查询时间,查询Linux系统最后重启时间的三个方法