Java基础、中级、高级、架构面试资料

JDK 27 增强 JFR,JEP 536 让密码等敏感数据不再裸奔

JAVA herman 15浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
【腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

市面上有不少围绕 AI 给微信搞出一些花样的开源项目,不少都是通过从内存中获取 SQLite 加密密钥获得破解的。

以前 Java 的一些密码框也可能被黑客通过内存数据读取获得破解,虽然后来做了加强。但 JFR 进程内数据脱敏方面始终是 Java 中长期被忽视的安全隐患。

JFR(JDK Flight Recorder)是 Java 生产环境诊断的“瑞士军刀”,但它存在一个严重的数据安全问题,像密码、Token、API Key 等敏感信息会以明文形式记录在 .jfr 文件中。为了解决这类问题,JDK 27 的 JEP 536 终于决定从源头解决这个问题了。所以,接下来,我就通过本文带领大家全面了解这个新特性的来龙去脉吧。

JEP 536 是什么?

全称是,JEP 536: JFR In-Process Data Redaction,翻译过来就是 JFR 进程内数据脱敏。

它能增强 JDK Flight Recorder,使其在数据离开进程之前就对命令行参数、环境变量和系统属性的初始值进行脱敏处理,防止敏感信息泄露。

简单来说,以前的 JFR 记录文件里密码是明文,现在默认变成 [REDACTED] 了。

文章配图参见 https://mp.weixin.qq.com/s/Lcp9pvGe74eaWlUBAqHiew

JEP 536 的时间线

JEP 536 这个特性从提出到正式 GA,不到 1 年时间,是 Java 里进展比较快的特性之一。上一次这么快落地的特性当属 Jdk 26 中 Comparator 新增的 min(T, T) 和 max(T, T) 默认方法,具体可以参考我的这篇文章《https://mp.weixin.qq.com/s/6JVvQQZdWoQlYQhSYQEFtA》。

下面这个表格是 JEP 536 的时间线。

时间节点事件
2025 年 11 月 30 日JEP 536 草案(Draft)首次提交,JBS Issue: JDK-8372760
2026 年 5 月 20 日Mark Reinhold 在 jdk-dev 邮件列表正式提议将 JEP 536 Target 到 JDK 27
2026 年 5 月 26 日JEP 536 正式被 Target 到 JDK 27(review 无异议通过)
2026 年 6 月 4 日JDK 27 进入 Rampdown Phase One(主分支冻结)
2026 年 9 月 14 日JDK 27 GA(正式发布)

截止目前,JEP 536 的状态为 Targeted,已确定随 JDK 27 一起发布。

为什么需要这个特性?

一切要从 JFR 的“安全隐患”说起。

密码正在 JFR 文件里裸奔

JFR 作为 HotSpot JVM 内置的低开销诊断框架,会记录大量运行时信息,包括下面几条。

  • jdk.InitialEnvironmentVariable —— 环境变量初始值
  • jdk.InitialSystemProperty —— 系统属性初始值
  • jdk.JVMInformation —— JVM 启动参数和命令行参数

这些信息对于排查问题非常有用,但它们往往包含敏感数据

$ export ACCESS_TOKEN=SECRET_TOKEN
$ java -XX:StartFlightRecording:filename=dump.jfr \
   -Xmx2G \
   -Djavax.net.ssl.keyStorePassword=SECRET_PASSWORD \
   -jar application.jar \
  --dbpassword ANOTHER_SECRET_PASSWORD

在上面这个例子中,生成的 dump.jfr 文件会明文记录三个秘密值。

敏感信息来源记录位置
SECRET_TOKEN环境变量 ACCESS_TOKENjdk.InitialEnvironmentVariable
SECRET_PASSWORD系统属性 javax.net.ssl.keyStorePasswordjdk.InitialSystemProperty
ANOTHER_SECRET_PASSWORD命令行 --dbpasswordjdk.JVMInformation

风险有多大?

主要体现在下面这 4 个方面。

  1. 共享诊断文件时泄露:将 .jfr 文件发送给同事、上传到工单系统、或存档到共享网络驱动器时,敏感信息随之扩散
  2. GDPR 合规风险:欧洲的开发者对此深有体会——历史 .jfr 日志中可能包含大量需要 GDPR 合规处理的敏感数据
  3. JVM 崩溃残留:事件数据在写入最终文件前会先写入临时目录,如果 JVM 崩溃,未脱敏的数据可能残留在临时目录中
  4. 流式传输风险:通过 FlightRecorderMXBeanRemoteRecordingStream 流式传输时,未脱敏数据可能直接离开主机

正如 JVM Weekly 的评论:“For years, JFR has been an invaluable production profiling tool… But it carried a dirty secret”。多年来,JFR 一直是宝贵的生产环境分析工具 …… 但它藏着一个肮脏的秘密。

JEP 536 是如何解决的?

进程内脱敏(In-Process Redaction)

核心的关键原则是,在数据离开 JVM 进程之前完成脱敏,而不是事后处理。

这意味着:

  • 临时文件中的数据也是脱敏后的
  • 流式传输的数据也是脱敏后的
  • 不需要事后手动运行 jfr scrub 命令

默认脱敏规则

JEP 536 引入了默认脱敏过滤器,无需任何配置即可保护大部分常见敏感字段,开箱即用。

默认 redact-key 过滤器(环境变量 & 系统属性)举例如下。

*api*key*
*auth*
*client*secret*
*credential*
*jaas*config*
*jwt*
*passphrase*
*passwd*
*password*
*private*key*
*pwd*
*secret*
*token*

默认 redact-argument 过滤器(命令行参数)如下。

-*api*key *
-*client*secret *
-*credential *
...(类似 redact-key,但支持多参数匹配)

具体的匹配规则有如下 3 条。

  • 不区分大小写
  • 使用 Glob 模式*? 作为通配符)
  • 匹配到的值替换为 [REDACTED]

使用方式

使用起来非常简单。通过 -XX:FlightRecorderOptions 的两个新子选项控制。

# 自定义脱敏规则
java -XX:FlightRecorderOptions:'redact-key=confidential,redact-argument=https://*:*@*' \
   -XX:StartFlightRecording:filename=dump.jfr \
   -jar application.jar

# 从文件加载过滤器
java '-XX:FlightRecorderOptions:redact-argument=@args.txt,redact-key=@keys.txt' ...

# 在默认规则基础上追加
java -XX:FlightRecorderOptions:'redact-key=+confidential;secret;@keys.txt' ...

# 完全禁用脱敏(恢复旧行为)
java -XX:FlightRecorderOptions:'redact-argument=none,redact-key=none' ...

多参数匹配

支持匹配参数序列,例如 --password SECRET 等。

# 匹配 --password 及其下一个参数
java -XX:FlightRecorderOptions:'redact-argument=--password *' ...

# 匹配 --password 及其后两个参数
java -XX:FlightRecorderOptions:'redact-argument=--password * *' ...

调试脱敏效果

可以执行下面的命令,查看输出结果。

# 开启调试日志,查看哪些参数被脱敏
java -Xlog:jfr+redact=debug ...

# 验证脱敏结果
jfr print --events InitialSystemProperty,JVMInformation,StringFlag,InitialEnvironmentVariable dump.jfr

输出示例。

jdk.InitialSystemProperty {
  key = "confidential"
  value = "[REDACTED]"
}

jdk.JVMInformation {
  jvmArguments = "-Dconfidential=[REDACTED]"
  javaArguments = "-jar application.jar [REDACTED] --verbose"
}

社区反响

JVM Weekly 在报道 JDK 27 特性时用了一个词评价 JEP 536,finally 终于。这代表了社区对这个长期存在问题的共同心声。

当然,在 JEP 536 之前,社区里也已经有了一些 临时解决方案 workaround。

方案缺点
jfr scrub 命令事后处理重复且容易出错;无法处理 JVM 崩溃残留
禁用特定事件(如 InitialEnvironmentVariable#enabled=false配置繁琐;可能误删非敏感数据
第三方工具 jfr-redact需要额外依赖;仍是事后处理

JEP 536 的设计者明确拒绝了这些替代方案,选择从源头解决问题。

为什么不用正则表达式?

JEP 文档中解释了为什么选用 Glob 模式而非正则表达式,给出了下面 3 个解释。

  1. HotSpot 的 C++ 正则库可能抛出异常,而 HotSpot 中禁止异常
  2. 使用 java.util.regex 会增加启动时间,且在某些场景下无法从 JVM upcall 到 Java
  3. 实践经验表明,正则表达式的表达能力很少是真正必需的

总结

JEP 536 是一个看似“较小”但影响深远的特性。它解决了 JFR 在生产环境使用中长期存在的安全隐患,体现了 Java 平台对安全默认(Secure by Default)原则的坚持。

它也带来了零配置安全、诊断能力不损失、透明可验证、安全共享、合规友好、降低人为失误、缩小攻击面、覆盖崩溃场景等方面的安全性。

当然,如果大家在某些场景下需要用到明文信息,或遇到技术问题,也可以选择回退到旧行为,只需添加下面的参数即可。

java -XX:FlightRecorderOptions:'redact-argument=none,redact-key=none' ...

控制,JDK 27 将于 2026 年 9 月 14 日正式发布。如果大家的生产环境大量使用 JFR 进行诊断,这个特性就非常值得大家的关注和升级了。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » JDK 27 增强 JFR,JEP 536 让密码等敏感数据不再裸奔