Spring Boot Actuator 被打穿:线上开了这些端点,等于裸奔

Spring Boot Actuator 被打穿:线上开了这些端点,等于裸奔

前段时间 CVE-2026-22733 暴出 Spring Boot 认证绕过漏洞,我们紧急排查了所有项目的 Actuator 配置。结果发现:一半以上的项目 Actuator 端点全开,没有任何鉴权。


一、事故现场

安全团队发来一封邮件:

紧急通知:检测到多个线上服务暴露了 Spring Boot Actuator 端点,/env、/heapdump、/shutdown 均可未授权访问。要求 24 小时内修复。

我一看,果然。我们的一个微服务,Actuator 配置长这样:

yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: "*"    # 所有端点全部暴露
  endpoint:
    shutdown:
      enabled: true      # 甚至开了远程关机

这意味着什么?任何人访问 http://你的域名/actuator/env 就能看到所有环境变量(包括数据库密码、Redis 密码、第三方 API Key)。访问 /actuator/heapdump 可以下载整个堆内存 dump,里面什么都有。访问 /actuator/shutdown 可以直接把服务关掉。

不是夸张,线上服务等于裸奔。


二、Actuator 到底暴露了什么

Spring Boot Actuator 是生产监控组件,提供一系列 HTTP 端点查看应用状态。问题在于很多人为了"方便调试"把所有端点都开了,却没加鉴权。

2.1 高危端点清单

端点 功能 危险等级 泄露什么
/actuator/env 查看所有环境变量 极高 数据库密码、Redis 密码、API Key
/actuator/heapdump 下载堆内存 dump 极高 堆里的所有对象(含密码、token、用户数据)
/actuator/shutdown 关闭应用 极高 直接让服务下线
/actuator/threaddump 线程转储 线程栈信息,可分析业务逻辑
/actuator/configprops 查看配置属性 数据源配置、连接池配置
/actuator/mappings 查看所有 URL 映射 暴露所有接口路径
/actuator/beans 查看所有 Spring Bean 暴露应用结构
/actuator/loggers 查看和修改日志级别 可动态调高日志级别导致磁盘写满
/actuator/health 健康检查 暴露数据库/Redis 连通性

2.2 CVE-2026-22733 的关键点

这个漏洞的核心是:当应用将需要认证的业务端点声明在 CloudFoundry Actuator 路径下(如 /cloudfoundryapplication/admin)时,攻击者可以通过该路径绕过 Spring Security 的认证。

简单说,Spring Security 对 Actuator 端点和普通业务端点的安全处理方式不同。如果你的业务接口恰好映射到了 Actuator 的路径下,它可能被当作 Actuator 端点处理,跳过了你配置的认证逻辑。

受影响版本:Spring Boot 2.7.0-2.7.31、3.3.0-3.3.17、3.4.0-3.4.14、3.5.0-3.5.11。修复版本:2.7.32、3.3.18、3.4.15、3.5.12。如果你的项目在这些范围内,尽快升级。


三、5 秒复现:你的服务裸奔了吗

3.1 检查你的配置

yaml 复制代码
# application.yml - 危险配置
management:
  endpoints:
    web:
      exposure:
        include: "*"      # ❌ 所有端点暴露
  endpoint:
    shutdown:
      enabled: true        # ❌ 远程关机
yaml 复制代码
# application.yml - 安全配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics    # ✅ 只开放必要端点
      base-path: /manage                # ✅ 改掉默认路径
  endpoint:
    shutdown:
      enabled: false                     # ✅ 关闭远程关机
  server:
    port: 9090                           # ✅ 独立端口,不跟业务端口混在一起

3.2 验证你的服务

直接在浏览器访问:

bash 复制代码
http://localhost:8080/actuator/env
http://localhost:8080/actuator/heapdump
http://localhost:8080/actuator/shutdown
  • 如果返回 JSON 数据(包含环境变量)→ 裸奔了,立刻修
  • 如果返回 404 → 端点没暴露,基本安全
  • 如果返回 401 → 有鉴权,问题不大

四、怎么修:3 层防护

第 1 层:最小化端点暴露(必须做)

yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
        exclude: env,heapdump,threaddump,beans,mappings,configprops
  endpoint:
    shutdown:
      enabled: false
    health:
      show-details: when-authorized   # 健康详情只给授权用户看

只开放运维必需的端点:health(健康检查)、info(应用信息)、metrics(指标)、prometheus(监控采集)。其余全部关闭。

注意 health.show-details:默认配置下 /actuator/health 会暴露数据库、Redis 的连通性详情。设成 when-authorized 让未授权用户只能看到 {"status":"UP"},看不到细节。

第 2 层:独立管理端口(强烈建议)

yaml 复制代码
management:
  server:
    port: 9090              # Actuator 端口跟业务端口分开
    address: 127.0.0.1      # 只允许本机访问(或内网 IP)

Actuator 跑在 9090 端口,业务跑在 8080。外部流量通过 Nginx 只转发 8080,9090 不对外暴露。监控系统从内网直接访问 9090 采集数据。

这是最有效的隔离方式:即使 Actuator 端点全开,外部也访问不到。

第 3 层:加鉴权(兜底)

java 复制代码
@Configuration
public class ActuatorSecurityConfig {

    @Bean
    SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/actuator/**")
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/actuator/health").permitAll()  // 健康检查放行
                .anyRequest().hasRole("ADMIN")                     // 其余需要 ADMIN 角色
            )
            .httpBasic(Customizer.withDefaults());                 // Basic 认证
        return http.build();
    }
}
yaml 复制代码
spring:
  security:
    user:
      name: monitor
      password: ${MONITOR_PASSWORD}   # 密码从环境变量读,别硬编码
      roles: ADMIN

即使前两层都失效,还有鉴权兜底。健康检查放行(K8s 探针需要),其余端点需要 ADMIN 权限。


五、heapdump 泄露了怎么办

如果之前线上裸奔过,/actuator/heapdump 可能已经被人下载了。堆内存里有什么?

  • 数据库连接字符串和密码
  • Redis 密码
  • JWT token / Session
  • 用户手机号、身份证号等业务数据
  • 第三方 API Key(支付、短信、OSS)

应急处理:

  1. 立刻改密码:数据库、Redis、所有第三方 API Key 全部轮换
  2. 检查访问日志 :看有没有异常 IP 访问过 /actuator/heapdump/actuator/env
  3. 检查依赖:确认 Spring Boot 版本不在 CVE-2026-22733 影响范围内(2.7.0-2.7.31、3.3.0-3.3.17、3.4.0-3.4.14、3.5.0-3.5.11),如果在就升级到对应修复版本
  4. 关闭端点:按上面的三层防护修复

六、CheckList:Actuator 安全排查

# 检查项 风险点 正确做法
1 include: "*" 所有端点暴露 只开放 health,info,metrics,prometheus
2 shutdown.enabled: true 远程关机 设为 false
3 没有独立端口 Actuator 跟业务混在一起 management.server.port 独立端口
4 管理端口对外暴露 任何人可访问 只绑定内网 IP 或 Nginx 不转发
5 没有鉴权 端点无保护 Spring Security 保护 + Basic 认证
6 health.show-details: always 暴露 DB/Redis 连通性 设为 when-authorized
7 Spring Boot 版本在 CVE 影响范围 认证绕过漏洞 升级到安全版本
8 之前裸奔过 密码可能已泄露 立即轮换所有密码和 API Key

七、总结

Actuator 是好东西,但全开等于给黑客送了一份应用说明书。环境变量、堆内存、线程栈、所有接口路径全都能看。

三层防护:

  1. 最小化暴露:只开 health,info,metrics,prometheus,关闭 shutdown
  2. 独立端口:management.server.port 跟业务端口分开,不对外暴露
  3. 加鉴权:Spring Security 保护,health 放行其余需要 ADMIN

如果之前裸奔过,别犹豫,立刻改密码,立刻关端点,立刻查日志


附录:安全配置模板

yaml 复制代码
# application.yml - Actuator 安全配置模板
management:
  server:
    port: 9090                          # 独立管理端口
    address: 127.0.0.1                  # 只允许本机访问(生产环境改内网 IP)
  
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
        exclude: env,heapdump,threaddump,beans,mappings,configprops,loggers
  
  endpoint:
    shutdown:
      enabled: false                    # 关闭远程关机
    health:
      show-details: when-authorized     # 健康详情只给授权用户
      show-components: never            # 不暴露组件详情
  
  info:
    env:
      enabled: false                    # 不暴露环境变量
    java:
      enabled: true                     # 只暴露 Java 版本信息

spring:
  security:
    user:
      name: ${MONITOR_USER:monitor}
      password: ${MONITOR_PASSWORD}     # 密码从环境变量读
      roles: ADMIN

直接复制这套配置到 application.yml,配合 Spring Security 依赖即可使用。 生产环境把 address 改成内网 IP,监控系统从内网访问 9090 端口采集数据。

相关推荐
Flynt1 小时前
从Spring Boot 4.0升到4.1,我在Maven和gRPC上栽了跟头
java·spring boot·后端
江华森2 小时前
Django 6.0 从入门到实战教程(上机实操版)
后端
ZhengEnCi3 小时前
J7A-高级Java工程师面试三道灵魂拷问-深度广度与工程素养的终极检验
java·后端
爱勇宝5 小时前
小红花成长新版:模板来了,鼓励也更容易开始
前端·后端·程序员
用户47949283569155 小时前
翻完 lark-cli 的 17 万行 Go 代码,我学到了什么
后端·openai
卷无止境6 小时前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
羑悻6 小时前
别再只接个 API 了!我用 EdgeOne Makers 手搓了一个“懂业务”的官网售前 AI
后端
卷无止境6 小时前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
程序员威哥6 小时前
零基础玩转西门子PLC:C#手撕S7协议,打造工业数据采集神器
后端