緊急!Spring Boot安全漏洞
環(huán)境:Spring Boot 2.7.18
1. 簡介
Spring Boot Actuator 模塊提供了 Spring Boot 生產(chǎn)就緒的所有功能。Actuator提供的所有接口可讓你監(jiān)控應(yīng)用程序各種信息并與之交互。Spring Boot 包含許多內(nèi)置接口,你還可以添加自定義的接口。例如,health 接口提供基本的應(yīng)用程序健康信息。有關(guān)Actuator的更多介紹可以查看官方文檔,本篇文章主要講解關(guān)于在生產(chǎn)環(huán)境中對Actuator的使用或控制不當(dāng),可能會(huì)引發(fā)安全隱患。為了避免這些問題,我們需要謹(jǐn)慎配置和使用Actuator。
2. 安全漏洞
當(dāng)在項(xiàng)目中啟用Actuator后,默認(rèn)情況下我們是可以沒有限制的訪問任意一個(gè)接口的,如下配置:
management:
endpoints:
web:
cors:
allow-credentials: true
allowed-headers: '*'
allowed-origins: ''
base-path: /ac
exposure:
include: '*'
以上配置,暴露了默認(rèn)Actuator的所有接口。而這些接口中有些接口暴露的信息就非常的敏感,如:/env,/configprops,/threaddump等接口,這些接口直接會(huì)將所有信息展現(xiàn)出來。
/configprops接口
圖片
/env接口
圖片
/threaddump接口
圖片
上面這些接口任其隨意訪問是有很大風(fēng)險(xiǎn)的(安全部門只要掃到你網(wǎng)站有這些問題都會(huì)通知你處理)尤其是上面的/configprops接口,很可能無意間就暴露了你的隱私信息。
3. 解決辦法
3.1 配置屬性
針對/configprops接口在上面的圖中你會(huì)發(fā)現(xiàn)對于password這樣的key系統(tǒng)默認(rèn)會(huì)進(jìn)行脫敏處理,在默認(rèn)情況下springboot會(huì)對如下的key進(jìn)行處理:以 "password"、"secret"、"key"、"token"、"vcap_services"、"sun.java.command "結(jié)尾的key都會(huì)被完全清除。
注意:只要是以這些key結(jié)尾的都會(huì)處理
自定義的屬性配置bean是否會(huì)處理呢?驗(yàn)證如下:
@ConfigurationProperties(prefix = "pack.sys")
public class PackProperties {
private String name ;
private String password ;
private String idNo ;
}
// 配置文件
pack:
sys:
name: pack
password: 123123
idNo: 11099111919919191
查看結(jié)果:
圖片
password字段被自動(dòng)的脫敏處理。但是對于這里的idNo我也希望能夠脫敏處理又該如何處理呢?通過修改字段名以支持SpringBoot支持的默認(rèn)命名規(guī)則,你應(yīng)該不會(huì)去修改字段名稱吧~!如下修改后的效果:
圖片
其實(shí)完全沒有必要這樣做,SpringBoot提供了自定義key的方式
management:
endpoint:
configprops:
additional-keys-to-sanitize:
- idNo
通過上面的屬性節(jié)點(diǎn),可以添加你需要處理的key。
圖片
當(dāng)你的key是以這種模式命名時(shí):.*credentials.* 包含credentials時(shí)系統(tǒng)也會(huì)自動(dòng)的進(jìn)行脫敏處理
圖片
此外,Spring Boot 還會(huì)對帶有以下結(jié)尾之一的key的 URI 類值的敏感部分進(jìn)行脫敏:
- address
- addresses
- uri
- uris
- url
- urls
URI 的敏感部分使用<scheme>://<username>:<password>@<host>:<port>/格式標(biāo)識(shí)。如下配置示例:
pack:
sys:
name: pack
password: 123123
idNo: 11099111919919191
packCredentials: 66666666
ftpUrl: ftp://pack:123456@xxxooo.pack.com/
展示結(jié)果:
圖片
自動(dòng)將密碼部分脫敏處理。
3.2 環(huán)境信息
對于/env接口,也是有對應(yīng)的配置屬性進(jìn)行配置
management:
endpoint:
env:
additional-keys-to-sanitize:
- port
- ... 添加更多的自定義key
與配置屬性一樣通過通用的方式添加額外的key進(jìn)行脫敏處理。
注意:對于env和configprops接口都有一個(gè)相同的屬性keys-to-sanitize,該屬性也可以定義你需要脫敏處理的key,該屬性有相同的默認(rèn)值:password,secret,key,token,.credentials.,vcap_services,sun.java.command
3.3 自定義脫敏規(guī)則
如果你希望更多的控制脫敏規(guī)則,那么你可以通過自定義SanitizingFunction Bean。
@Component
public class PackSanitizingFunction implements SanitizingFunction {
@Override
public SanitizableData apply(SanitizableData data) {
if (data.getKey().endsWith("email")) {
return data.withValue("###") ;
}
return data ;
}
}
輸出結(jié)果:
圖片
3.4 其它接口安全配置
對于像/threaddump,/heapdump這樣的接口,我們要么將其禁用,要么通過Spring Security進(jìn)行安全控制,如下示例通過Spring Security進(jìn)行安全控制。
@Bean
SecurityFilterChain actuatorSecurityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable());
http.authorizeHttpRequests().antMatchers("/ac/env").hasRole("ADMIN") ;
http.authorizeHttpRequests().antMatchers("/ac/**").hasRole("ACTUATOR") ;
http.authorizeHttpRequests().anyRequest().permitAll() ;
http.formLogin(customizer -> Customizer.withDefaults()) ;
return http.build() ;
}
基于用到了Security,你完全可以對所有的接口進(jìn)行攔截控制,也就沒必要進(jìn)行上面那些操作了。