背景
最近整理历史安全巡检记录时,发现 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/beans | Bean 信息 | 暴露组件结构和框架依赖 |
/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 等必要端点;管理端口与业务端口分离;网络层限制来源;敏感端点必须认证授权;配置和日志中的密钥同步治理。这样既不影响运维观测,也能把风险控制在可接受范围内。
推荐意见