当前位置: 首页 > news >正文

Spring Boot Actuator 暴露 heapdump,内存里的密码可能全漏了

Spring Boot Actuator 暴露 heapdump,内存里的密码可能全漏了

线上开了 Actuator,本来是为了方便排查问题。

结果/actuator/heapdump也暴露出去了。

一份堆转储文件下载下来,数据库连接串、Redis 密码、Token、用户请求参数,都可能躺在里面。


一、事故现场

有个项目为了方便线上排查,开了 Spring Boot Actuator。

配置大概是这样:

management:endpoints:web:exposure:include:"*"

开发同学当时的想法很简单:

先全部打开,线上排查方便一点。

结果某天安全扫描扫出来:

/actuator/env /actuator/metrics /actuator/heapdump /actuator/threaddump

这些端点都能访问。

其中最危险的是:

/actuator/heapdump

这个接口会导出 JVM 当前堆内存快照。

换句话说:

JVM 里活着的对象,它都可能出现在 heapdump 里。

这就不是“暴露一点监控信息”的问题了。

这是把应用内存打包交出去了。


二、heapdump 里到底有什么?

很多人低估了 heapdump 的敏感程度。

它不是普通日志。

它是 JVM 堆内存快照。

里面可能包含:

配置对象 数据库连接信息 Redis 连接信息 MQ 连接信息 第三方 API Token JWT / Session / Cookie 用户请求参数 接口返回数据 缓存对象 业务实体 异常堆栈 临时字符串

比如项目里有这种配置:

spring:datasource:url:jdbc:mysql://10.0.0.12:3306/order_dbusername:order_userpassword:Abc123456redis:host:10.0.0.20password:redis-secret

这些配置在应用启动后,通常会被绑定成 Java 对象。

只要对象还在堆里,就有可能出现在 heapdump 文件中。

再比如请求里带了 Token:

Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

或者用户刚提交过敏感参数:

{"mobile":"13800000000","idCard":"xxx","password":"xxx"}

这些字符串如果还没被 GC,也可能在堆快照里被找到。

所以 heapdump 暴露的风险不是“看一下内存占用”。

而是:

把应用运行时的敏感数据一起暴露了。


三、为什么很多项目会误开?

最常见的是这行配置:

management:endpoints:web:exposure:include:"*"

这表示暴露所有 Web 端点。

开发环境这么配,问题不大。

但如果生产也这么配,就危险了。

还有一种写法:

management:endpoints:web:exposure:include:health,info,metrics,env,heapdump,threaddump

看起来比*收敛了一点。

heapdumpenvthreaddump仍然是高风险端点。

尤其是这些:

端点风险
/actuator/heapdump导出 JVM 堆内存,可能包含密码、Token、用户数据
/actuator/env暴露环境变量、配置项和配置来源;旧版本或配置不当时可能泄露敏感值
/actuator/configprops暴露配置绑定对象;旧版本或配置不当时可能泄露敏感值
/actuator/threaddump暴露线程栈、类名、方法名、业务路径
/actuator/logfile暴露日志内容
/actuator/mappings暴露接口路由

这些东西对开发排查很方便。

对攻击者也很方便。

这里要补一个版本细节。

较新的 Spring Boot 对/actuator/env/actuator/configprops这类端点默认会做敏感值脱敏,很多密码字段不会直接明文展示。

但这不代表它们就可以放心暴露。

因为它们仍然会暴露配置结构、属性名、配置来源、组件信息和内部实现细节。如果项目使用旧版本、改过脱敏规则,或者把show-values配成了always,敏感值仍然可能被打出来。

/actuator/heapdump的风险更直接。

它导出的是堆内存快照,不是经过脱敏处理的配置视图。


四、Actuator 默认不是原罪,乱暴露才是

Actuator 本身不是问题。

它是非常好用的生产诊断工具。

问题在于:

暴露范围太大 没有鉴权 直接挂公网 生产和开发共用一套配置

安全的做法不是“永远不用 Actuator”。

而是生产环境只开放必要端点。

比如最小配置:

management:endpoints:web:exposure:include:health,info

如果接入 Prometheus:

management:endpoints:web:exposure:include:health,info,prometheus

不要为了省事写:

include:"*"

这行配置在生产环境里非常刺眼。


五、生产环境应该怎么配?

1. 只暴露必要端点

推荐:

management:endpoints:web:exposure:include:health,info,prometheus

不推荐:

management:endpoints:web:exposure:include:"*"

如果没有监控采集需求,甚至可以只留:

management:endpoints:web:exposure:include:health

2. health 不要暴露过多细节

很多项目会开:

management:endpoint:health:show-details:always

这会把很多健康检查细节暴露出去。

生产环境更建议:

management:endpoint:health:show-details:never

或者只对已认证用户展示:

management:endpoint:health:show-details:when_authorized

3. 管理端口和业务端口分开

可以把 Actuator 放到单独端口:

management:server:port:9090

然后通过安全组、内网、防火墙限制访问。

比如:

业务端口 8080:对外开放 管理端口 9090:只允许内网监控系统访问

这样即使业务接口暴露公网,管理端点也不会跟着裸奔。

4. 加鉴权

如果管理端点必须通过 HTTP 访问,至少要加鉴权。

比如只允许管理员角色访问:

@ConfigurationpublicclassActuatorSecurityConfig{@BeanSecurityFilterChainactuatorSecurityFilterChain(HttpSecurityhttp)throwsException{http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests(auth->auth.requestMatchers(EndpointRequest.to("health","info")).permitAll().anyRequest().hasRole("ACTUATOR_ADMIN")).httpBasic(Customizer.withDefaults());returnhttp.build();}}

具体写法会随 Spring Security 版本变化,但原则不变:

非公开端点必须鉴权。

5. 明确关闭高危端点

如果不需要 heapdump,可以显式关掉:

management:endpoint:heapdump:enabled:false

也可以关闭其他高危端点:

management:endpoint:env:enabled:falseconfigprops:enabled:falsethreaddump:enabled:falselogfile:enabled:false

注意:端点“启用”和“暴露”是两回事。

一个端点可能在应用内部启用了,但没有通过 Web 暴露。

在较新的 Spring Boot 版本里,还可以额外通过端点访问级别控制某个端点是不可访问、只读,还是允许完整访问。不同版本的配置项名字会有差异,落地时要按自己项目的 Spring Boot 版本确认。

生产环境要同时关注:

enabled exposure access network access authentication

如果确实需要临时开放envconfigprops给内网排查,至少不要在生产环境使用:

management:endpoint:env:show-values:alwaysconfigprops:show-values:always

更稳的做法是保持敏感值不展示,或者只对已认证、已授权的用户展示。


六、已经暴露过 heapdump,怎么办?

如果你发现生产环境曾经暴露过/actuator/heapdump,不要只把配置改掉就结束。

建议按事故处理。

1. 立即下线暴露端点

先改配置:

management:endpoints:web:exposure:include:health,info,prometheusendpoint:heapdump:enabled:false

同时确认网关、Nginx、安全组没有继续放行。

2. 检查访问日志

查这些路径有没有被访问过:

/actuator /actuator/heapdump /actuator/env /actuator/configprops /actuator/threaddump /actuator/logfile

重点看:

访问 IP 访问时间 响应状态码 响应大小 是否有异常下载流量

如果/actuator/heapdump返回过大文件,就要高度警惕。

3. 轮换密钥和密码

heapdump 里可能出现这些敏感信息:

数据库密码 Redis 密码 MQ 密码 对象存储密钥 第三方 API Token JWT 签名密钥 内部服务调用凭证

如果确认有外部访问,建议轮换相关凭证。

不要赌“没人会分析那个文件”。

4. 检查异常登录和异常调用

如果数据库、Redis、对象存储、第三方平台有审计日志,要一起看。

重点看:

陌生 IP 登录 异常时间段访问 大量读取 失败重试 权限变更 新增账号

Actuator 泄露本身只是入口。

真正的损失可能发生在后面。


七、团队规范:生产 Actuator 最小化

如果让我给团队定一条规范,我会这样写:

生产环境禁止 exposure.include=* 生产环境默认只开放 health、info、prometheus heapdump、threaddump、logfile 不允许公网访问 env、configprops 不允许公网访问,确需内网开放时也不要展示敏感值 管理端口必须走内网或鉴权 所有 Actuator 配置必须区分 dev/test/prod

配置可以分环境。

开发环境:

# application-dev.ymlmanagement:endpoints:web:exposure:include:"*"endpoint:health:show-details:always

生产环境:

# application-prod.ymlmanagement:endpoints:web:exposure:include:health,info,prometheusendpoint:health:show-details:neverheapdump:enabled:falseenv:enabled:falseconfigprops:enabled:falsethreaddump:enabled:falselogfile:enabled:false

这才是比较稳的方式。

不要让开发配置跟着一起上生产。


八、上线前 checklist

上线前看到 Actuator,建议过一遍这个表。

检查项风险建议
是否配置include: "*"所有端点暴露生产禁止
是否暴露heapdump堆内存泄露关闭或仅内网鉴权
是否暴露env配置结构、环境变量和敏感值泄露风险关闭;确需开放时鉴权并避免show-values: always
是否暴露configprops配置对象和敏感值泄露风险关闭;确需开放时鉴权并避免show-values: always
是否暴露logfile日志敏感信息泄露关闭
管理端口是否公网可访问被扫描命中内网隔离
health 是否展示详情泄露组件信息prod 用never
dev/prod 配置是否隔离开发配置上生产分环境配置
是否有访问日志暴露后难追踪网关/Nginx 留日志

九、总结

Actuator 是好工具。

但生产环境里,它不是给所有人看的。

尤其是/actuator/heapdump

它导出的不是普通监控数据,而是 JVM 堆内存快照。

里面可能有:

密码 Token 连接串 用户数据 业务对象 请求参数

所以生产环境记住三句话:

不要include: "*"

不要把管理端点挂公网。

不要无鉴权暴露 heapdump、env、configprops、logfile 这类高危端点。

下一篇准备写:@Async 默认执行器又炸了:SimpleAsyncTaskExecutor 为什么不是线程池

如果你也在排查 Java 后端线上问题,可以关注公众号:云技纵横。

这个系列会持续更新 Spring 事务、线程池、JVM、MySQL、Redis、MQ 的真实踩坑复现。

http://www.gsyq.cn/news/1646967.html

相关文章:

  • Spring Data Commons CVE-2018-1273漏洞剖析:SpEL表达式注入与RCE实战
  • 北京通州有哪些值得推荐的学画画的美术机构?
  • CloudFormation Stack 概念全解析:从资源集合到自动化编排的核心引擎
  • 万能密码漏洞:认证逻辑缺陷的深度剖析与防御实践
  • 2026年最新八字排盘应用推荐:天乙八字排盘、命枢、问真八字等怎么选?
  • 【JavaWeb】三大组件之——Servlet
  • EMA 指数移动平均 PyTorch 实现:3 种主流框架集成方案与性能开销实测
  • 类与对象:蓝图和房子的关系
  • 影刀RPA学习路线图:从小白到独立开发的完整学习路径
  • MediaCrawler-new:多平台社交媒体数据采集技术框架与自动化解决方案
  • 5分钟快速上手TEdit:泰拉瑞亚地图编辑器的终极指南
  • 《在飞机上偶遇前任后》穗雪|小说|txt下载|番外|免费阅读
  • AI生成图片文字模糊?AnyText技术原理与实战指南
  • 2026视频转文字工具选择指南:拆解免费付费坑点,看懂隐私、水印、收费套路避踩雷
  • 第48期 OpenAI的钱都花哪了?Capex支出全景调研
  • 《从 300 行到 30 万行代码,我学到的 5 个重构教训》
  • 城市违章搭建识别、棚户区语义分割与YOLO格式数据集:基于深度学习的城市治理AI实践全解析10693期
  • 质量管理必备的10个基本思维方式
  • 抖音无水印视频下载神器:从零开始掌握批量下载技巧
  • Grafana Dashboard JSON 文件详解
  • 《被错认成道侣后》山野行月|小说|txt下载|全文
  • 《夫人要和离》藤鹿山|小说|txt下载|番外|免费阅读
  • 使用Let‘s Encrypt与Certbot为Nginx网站免费配置HTTPS及自动续期
  • ArcGIS Pro 3.2 遥感影像语义分割标签制作:矢量转栅格3大坐标系对齐要点
  • 多模态 Agent 视觉理解:VLM + 工具调用的工程落地
  • 从源码角度理解Java并发编程面试题
  • 115proxy-for-kodi终极指南:让电视直接播放115云盘视频的完整教程
  • MySQL 基本命令操作大全(从入门到熟练)
  • PoisonSeed攻击深度解析:FIDO2未破,认证降级漏洞与防御实战
  • 携程酒店价格库存实时监控变化(python实现)