說說Gateway Actuator的安全漏洞 Index: 0, Size: 0
時間:2022年3月
背景:做為Java開發人員,肯定會用到很多開源技術框架,而這些開源框架在不同的時候總會被爆出有各種安全漏洞,早在1月份log4j被爆出有安全漏洞,各個應用服務緊急升級,但是沒遇到過漏洞被攻擊的場景。而這次Gateway Actuator被爆出高危漏洞讓我有了深刻的體會。
美好的一天,從我寫詩一樣的程式碼開始的,到10點半左右,技術經理收到安全部門郵件,轉告我們Actuator被爆出高危漏洞,讓今天必須解決。What? Actuator是什麼漏洞,baidu一下?沒有發現。什麼漏洞?怎麼解決?安全部門郵件也沒有說。正在一籌莫展的時候,線上環境出現Bug,很多介面請求都請求失敗,報錯資訊:Index: 0, Size: 0 這是什麼鬼?
先排查線上日誌,很快定位到Gateway服務報錯,原本5臺Gateway例項,其中2臺都是這個錯誤,等於40%的請求,任何介面,只要打到這2臺錯誤的Gateway的請求,全部請求失敗。錯誤日誌如下:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:657) ~[na:1.8.0_252] at java.util.ArrayList.get(ArrayList.java:433) ~[na:1.8.0_252] at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.combinePredicates(RouteDefinitionRouteLocator.java:219) ~[spring-cloud-gateway-core-2.1.1.RELEASE.jar:2.1.1.RELEASE] at org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator.convertToRoute(RouteDefinitionRouteLocator.java:143) ~[spring-cloud-gateway-core-2.1.1.RELEASE.jar:2.1.1.RELEASE] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100) ~[reactor-core-3.2.8.RELEASE.jar:3.2.8.RELEASE] at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.onNext(ScopePassingSpanSubscriber.java:96) ~[spring-cloud-sleuth-core-2.1.1.RELEASE.jar:2.1.1.RELEASE]
在Gateway-core的報錯原始碼如下:
private AsyncPredicate<ServerWebExchange> combinePredicates( RouteDefinition routeDefinition) { List<PredicateDefinition> predicates = routeDefinition.getPredicates(); AsyncPredicate<ServerWebExchange> predicate = lookup(routeDefinition, predicates.get(0)); for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) { AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate); predicate = predicate.and(found); } return predicate; }
紅色字型這塊,表示從route配置中獲取 predicates 是空的,所以才報Index: 0, Size: 0錯誤。要知道route路由配置中,prodicate是必填的,不允許為空,要不Gateway都啟動不了。
檢視Gateway配置檔案,沒改動過,服務例項也沒重啟過。
在沒找到問題的情況,臨時解決方案就是重啟出現問題的Gateway,重啟後恢復正常了,後來總有幾個Gateway例項不停的報錯。
這時我們通過錯誤的時間點,在waf上找一找有沒有異常的請求。在參照Gateway與Actuator整合的API,找到了如下介面。
如果Gateway和Actuator整合後,是可以提供動態操作route路由的介面的。
建立路由,傳送Post請求:/gateway/routes/{id_route_to_create}
刪除路由,傳送Delete請求:/gateway/routes/{id_route_to_delete}
如果使用建立路由介面,引數是一個不完整的route(因為這個介面沒有任何引數校驗),就會報我們專案的錯誤。既然BUG復現了,解決方案就好辦了,禁用Gateway專用的Actuator介面。
management.endpoint.gateway.enabled=false
2天后,我才在我們關注的眾多公眾號上看到Gateway Actuator漏洞的相關文章。和安全部門同步訊息之後,才確認就是這個漏洞。
我們折騰了一天,也辛苦了不停重啟服務的DevOps。