跳转到帖子

背景

最近整理历史安全巡检记录时,发现 Spring Boot Actuator 管理接口暴露仍然是企业内网和测试环境里很常见的问题。它不一定直接等同于高危漏洞,但在真实攻防里,经常会成为信息收集、横向定位、配置泄露甚至进一步利用的入口。

这篇文章不写攻击链细节,也不讨论未授权利用手法,主要从防守视角复盘一个典型场景:某业务系统将 Actuator 暴露在办公网和部分公网出口后,导致应用运行状态、环境变量、路由信息、Bean 信息被非预期访问。文章重点放在如何识别风险、判断影响面,以及如何做可落地的加固。

问题场景

目标系统是一个常见的 Java 微服务,使用 Spring Boot 2.x,接入了注册中心、配置中心、Redis、MySQL 和消息队列。由于早期为了方便排障,研发在配置中启用了较多 Actuator endpoint,并且网关层没有针对管理路径做单独访问控制。

风险点主要集中在以下几类:

  • /actuator 入口可被非运维人员访问。
  • /actuator/env、/actuator/configprops 等接口暴露敏感配置键名或部分值。
  • /actuator/mappings 暴露内部接口路由、控制器方法和请求路径。
  • /actuator/beans 暴露应用组件结构,便于判断技术栈和关键依赖。
  • 历史环境中曾启用过危险 endpoint,例如 heapdump、threaddump、logfile。
Actuator 本身是运维观测能力,不是漏洞。但一旦暴露范围和权限控制不当,就会变成高价值信息源。

技术分析

Spring Boot Actuator 的设计目标是提供应用健康检查、指标采集、审计和运行时观测能力。常见 endpoint 包括:

Endpoint用途风险关注点
/actuator/health健康检查可能泄露组件存活状态、依赖服务状态
/actuator/env环境变量与配置属性可能出现数据库、缓存、第三方服务配置痕迹
/actuator/mappings请求映射关系暴露接口结构、内部路径、控制器方法
/actuator/beansBean 信息暴露组件结构和框架依赖
/actuator/heapdump堆转储可能包含运行时敏感对象,应严格禁止公网访问
/actuator/logfile日志文件可能包含请求参数、异常堆栈、用户标识

在 Spring Boot 2.x 之后,Actuator 默认暴露策略已经比早期版本更保守,但很多项目会在配置中主动放开:

management.endpoints.web.exposure.include=*

这类配置在开发环境很常见,如果没有区分环境直接带到测试或生产,就会形成明显风险。尤其在微服务场景下,某些服务虽然没有公网入口,但可能被网关、Ingress、Nginx 或办公网代理间接暴露。

排查思路

排查时建议不要只看代码仓库里的配置文件,还要结合实际运行环境。很多配置可能来自启动参数、环境变量、配置中心或容器编排平台。

可以从以下几个层面检查:

  • 应用配置:检查 application.yml、application-prod.yml、配置中心中的 management.* 配置。
  • 启动参数:检查 JVM 参数、容器启动命令、Kubernetes Deployment 环境变量。
  • 网关规则:确认 /actuator、/manage 等路径是否被路由到后端服务。
  • 网络边界:确认管理端口是否被安全组、ACL、防火墙限制。
  • 认证授权:确认管理接口是否纳入统一认证,是否区分普通用户和运维角色。

常见配置检查命令如下,仅用于自查本机或授权环境:

grep -R "management.endpoints.web.exposure" ./config ./src/main/resources

grep -R "management.endpoint" ./config ./src/main/resources

grep -R "management.server" ./config ./src/main/resources

如果服务运行在 Kubernetes 中,可以重点查看环境变量和启动参数:

kubectl get deploy -n your-namespace your-app -o yaml | grep -i "management" -C 3

kubectl get ingress -n your-namespace | grep -i your-app

推荐加固方案

比较稳妥的策略是:只暴露必要 endpoint,只允许受控网络访问,敏感接口必须有认证授权,生产环境禁止使用通配符。

一个相对保守的生产配置示例:

management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.health.show-details=never
management.server.port=18080
management.server.address=127.0.0.1

如果需要被 Prometheus 采集,建议通过内网、ServiceMonitor 或专用采集网络访问,不建议直接暴露到公网。对于 Kubernetes 环境,可以将管理端口仅作为 ClusterIP 服务暴露,并配合 NetworkPolicy 限制来源。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-prometheus-to-actuator
  namespace: app-namespace
spec:
  podSelector:
    matchLabels:
      app: your-app
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: monitoring
      ports:
        - protocol: TCP
          port: 18080

如果必须通过网关访问管理接口,建议单独做路径级访问控制,例如只允许运维网段或通过统一身份认证后访问:

location /actuator/ {
    allow 10.10.0.0/16;
    deny all;
    proxy_pass 
}

代码层面的控制

除了网络层限制,也可以在 Spring Security 中对管理端点单独授权。示例仅表达思路,实际应结合项目使用的 Spring Security 版本调整写法:

@Bean
SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
    http
        .securityMatcher(EndpointRequest.toAnyEndpoint())
        .authorizeHttpRequests(auth -> auth
            .requestMatchers(EndpointRequest.to("health", "info")).permitAll()
            .anyRequest().hasRole("OPS")
        )
        .httpBasic(Customizer.withDefaults());
    return http.build();
}

这里的重点不是使用 Basic Auth,而是将管理接口和业务接口分开建模。很多项目只给业务 API 做了权限控制,却忽略了 Actuator、Swagger、Druid、H2 Console、内部调试接口这些“非业务入口”。

敏感信息治理

即使接口访问控制已经补上,也建议同步检查配置和日志中是否存在敏感信息。Actuator 风险经常暴露出更底层的问题:密钥散落、日志过度打印、配置中心权限粗放。

  • 数据库、Redis、MQ 密码应使用密钥管理系统或平台 Secret,不应明文写入仓库。
  • 第三方 API Token 不应出现在日志、异常堆栈、启动参数中。
  • 配置中心应区分环境和角色,研发、测试、运维权限不应完全一致。
  • 定期轮换历史泄露过的凭据,不要只做接口下线。
  • 对日志采集平台设置字段脱敏规则,例如手机号、身份证、Token、Cookie。

如果曾经暴露过 heapdump 或 logfile,建议按泄露事件处理,而不是简单关闭接口。因为堆文件和日志中可能存在会话、Token、连接串、用户数据等,需要评估访问日志、下载记录和凭据轮换范围。

事件复盘中的几个注意点

  • 不要只在应用侧修复。需要同时检查网关、Ingress、安全组、ACL、监控采集链路。
  • 不要只修一个服务。Actuator 暴露往往是脚手架或模板配置问题,应批量排查同类项目。
  • 不要直接删除健康检查。健康检查对发布和监控很重要,正确做法是最小化暴露和限制访问源。
  • 不要依赖路径隐藏。将 /actuator 改成非常规路径只能降低误扫概率,不能替代认证授权。
  • 不要忽视测试环境。测试环境经常连接准生产数据或共享中间件,风险不一定比生产低。

落地检查清单

  • 生产环境是否存在 management.endpoints.web.exposure.include=*。
  • env、beans、mappings、heapdump、logfile 是否被暴露。
  • 管理端口是否与业务端口分离。
  • 管理端口是否只监听内网地址或本地地址。
  • 网关、Ingress、Nginx 是否放行 /actuator。
  • Prometheus 等采集端是否通过受控网络访问。
  • Spring Security 是否对敏感 endpoint 做角色限制。
  • 配置中心、容器环境变量中是否存在明文敏感信息。
  • 历史日志和堆文件是否可能包含凭据。
  • 是否已将该检查项加入发布前安全基线。

总结

Actuator 暴露问题的本质不是某个接口危险,而是管理面和业务面边界不清。很多团队在开发阶段为了排障方便放开了管理能力,但上线后没有回收,最终形成持续暴露的信息入口。

比较可靠的治理方式是把它纳入工程化基线:默认只开放 health、info、prometheus 等必要端点;管理端口与业务端口分离;网络层限制来源;敏感端点必须认证授权;配置和日志中的密钥同步治理。这样既不影响运维观测,也能把风险控制在可接受范围内。

代码审计与漏洞定位示意图
代码审计、调用链与关键函数定位示意

0篇意见

推荐意见

没有意见。

游客
抱歉,你的帖子内容包括我们不允许的字词。请编辑你的帖子,删除下面高亮的屏蔽字。
添加意见…