本文转载自微信公众号《桐人的技术分享》,作者kiritomoe。转载本文请联系桐人的技术分享公众号。前言一年一度的硬件运营开始了。最近,我对各种安全漏洞感到特别困扰。我可以在一周内收到安全团队扫描的数十封漏洞电子邮件。其中,有一类漏洞容易被忽视,但影响范围广,危害大。说它的名字大家应该不会觉得陌生,它就是SpringBootActuator。在写这篇文章之前,我和朋友们做了一个小调查,询问他们对SpringBootActuator的理解。结果出奇地一致。大家都知道SpringBoot提供了spring-boot-starter-actuator的自动配置,但是却很少有人真正去使用它的相关特性。当你继续阅读下面这篇文章时,你也可以先思考以下问题:查看你开发的项目中是否引入了spring-boot-starter-actuator依赖?你真的在你的项目中使用spring-boot吗?-你知道-starter-actuator的相关功能吗?spring-boot-starter-actuator的安全隐患和正确配置方法你知道吗?什么是SpringBoot执行器?Actuator,我专门翻阅了它的文档,找到了官方定义Actuator的定义Actuator是一个制造术语,指的是用于移动或控制某物的机械装置。执行器可以通过微小的变化产生大量的运动。好家伙,读了也没用。以我的英语六级水平,看懂这段话确实有难度。希望有英文好的同学帮我翻译一下。我只能根据个人对SpringBootActuator功能的理解来意译一下:我们可以通过SpringBootActuator来查看SpringBoot应用的健康状态、环境配置、Metrics、Trace、Spring上下文等信息,除了一系列In除了查看功能,还实现了SpringBoot应用的上下线和内存转储功能。快速入门第一步引入依赖提示:spring-boot-starter-actuator在不同版本的SpringBoot中有一定的配置差异。本文使用最新版本2.4.4org.springframework.bootspring-boot-starter-actuator2.4.4第二步了解endpointendpoint是我们在使用SpringBootActuator时最需要关心的对象。List一些你可能感兴趣的端点IDDescriptionbeans查看Spring容器中的所有对象configprops查看@ConfigurationPropertiesenv修改的对象列表查看application.yaml配置的环境配置信息healthhealthcheckendpointinfoapplicationinformationmetricsstatisticsmappingsservicecontract@RequestMapping相关的端点shutdown优雅下线,比如health,只需要访问下面的end点可以获取应用程序的状态curl"localhost:8080/actuator/health"第三步,了解端点的启用和暴露状态。SpringBootActuator为所有端点提供了两种配置。启用状态默认是启用的,除了shutdown之外,其他端点都是启用的。这也很好理解。其他端点基本都是检查行为,但是shutdown会影响应用的运行状态。曝光曝光状态。端点的enabled设置为true后,需要暴露一次才可以访问。默认情况下,仅公开健康和信息。当enabled不启用时,相关端点代码根本不会被Spring上下文加载,所以当enabled为false时,暴露配置也无济于事。几个典型的配置示例如下,开启和暴露所有endpointsmanagement:endpoints:web:exposure:include:"*"endpoint:shutdown:enabled:true只开启和暴露指定的endpointmanagement:endpoints:enabled-by-default:falseendpoint:info:enabled:trueendpoints:web:exposure:include:"info"禁用所有endpointmanagement:endpoints:enabled-by-default:false或者,移除spring-boot-starter-actuator依赖!了解SpringBootActuator的安全风险从上面的介绍可以看出,SpringBootActuator提供的一些端点会暴露重要的应用信息。以env为例感受下典型的application.yaml例子。server:port:8080spring:datasource:url:jdbc:mysql://testDbHost:3306/kiritousername:kiritopassword:123456kirito:ak:kirito@xxx_aksk:kirito@xxx_skmanagement:endpoints:web:exposure:include:"*"以上配置但是经典的,我们看看访问localhost:8080/actuator/env后的返回值{"activeProfiles":[],"propertySources":[{"name":"server.ports","properties":{"local.server.port":{"value":8080}}},{"name":"Configresource'classpathresource[application.yaml]'vialocation'optional:classpath:/'","properties":{"server.port":{"value":8080,"origin":"classpathresource[application.yaml]-2:9"},"spring.datasource.url":{"value":"jdbc:mysql://testDbHost:3306/kirito","origin":"classpathresource[application.yaml]-5:44"},"spring.datasource.username":{"value":"kirito","origin";:"classpathresource[application.yaml]-6:15"},"spring.datasource.password":{"value":"******","origin":"classpathresource[application.yaml]-7:15"},"kirito.ak":{"value":"kirito@xxx_ak","origin":"classpathresource[application.yaml]-10:7"},"kirito.sk":{"value":"kirito@xxx_sk","origin":"classpathresource[application.yaml]-11:7"},"management.endpoints.web.exposure.include":{"value":"*","origin":"classpathresource[application.yaml]-17:18"}}}]}可以发现对于spring.datasource.password内置的敏感配置信息,SpringBootActuator是脱敏的,但是对一些自定义敏感暴露了kirito.ak和kirito.sk等配置。可能有读者马上会质疑:我们的机器部署在内网,一般都是通过反向代理对外暴露的服务。外部用户是否可以访问这种端点。那我只能说太天真了。例如,以下情况是导致安全漏洞的真实案例:反向代理错误配置了根节点,将执行器的端点和Web服务一起暴露。线上配置没有问题,测试环境部署公网SLB激活时,actuator端点暴露。同一环境中的一台机器被攻破,导致应用配置信息泄露。安全建议对于SpringBootActuator提供的端点,可以采取以下措施,尽可能降低安全风险。攻击风险是暴露端点的最小粒度。仅启用和公开实际使用的端点,而不是配置:management.endpoints.web.exposure.include=*。为端点配置一个独立的访问端口,使其与web服务的端口分离,避免在暴露web服务时误暴露执行器的端点。示例:management.port=8099。引入spring-boot-starter-security依赖来配置执行器端点的访问控制。仔细评估是否引入spring-boot-stater-actuator。以我个人的经验,目前还没有遇到必须引入spring-boot-stater-actuator才能解决的需求。如果你不理解上面提到的安全风险,我建议你先去掉这个依赖。今天你用过SpringBootActuator了吗?