大家好,我是魚皮,開門見山,知名的開源專案 Apache Log4j 出事了!
2021 年 12 月 9 日,該專案被曝存在 嚴重安全漏洞 ,攻擊者只需要向目標機傳入一段特殊程式碼,就能觸發漏洞,自由地在遠端執行任意程式碼來控制目標機器!
老實說,光聽到這個訊息,我就覺得很可怕了。因為 Log4j 作為 Java 的知名日誌記錄框架,憑藉其靈活高效的日誌生成能力,不僅被眾多自研專案所使用,還被很多明星專案作為了基礎框架使用,像 Redis、Kafka、Elasticsearch、Apache Flink、Apache Druid 等等。可以想象這個漏洞的影響範圍有多大,甚至被很多媒體稱之為 “核彈級” 漏洞!
在漏洞被曝光之後,第一時間做出行動的不是無辜躺槍的程式設計師們,而是那些壞的一批的小子們。據說,在漏洞被公開的第一天,就發生了近萬次利用該漏洞的攻擊行為!
漏洞細節
根據 CVE 漏洞公開網站的記錄,該漏洞存在於 Apache log4j <= 2.14.1 的版本(但事實上,影響的版本範圍比這更大)。攻擊者可以通過 log4j 的 lookup 替換功能向其配置檔案的任意位置注入程式碼(類似 SQL 注入,把 ${變數} 替換為 ${實際程式碼}),再加上這些版本中用到的 JNDI 特性並沒有為 LDAP 提供足夠的保護,使得注入的任意程式碼都能被肆無忌憚地執行。
JNDI:Java 命名與目錄介面,提供了用名稱來訪問資源的能力
LDAP:輕型目錄訪問協議,定義瞭如何訪問目錄服務中的內容
兩者配合,可以完成對伺服器目錄的操作,比如增刪改查。
有一些用 Minecraft Java 版本開服的小夥伴就被坑了,因為該專案用到了 log4j 來記錄使用者聊天日誌,因此玩家只需要在聊天視窗輸入一些這個那個的命令程式碼,就被注入執行了,從而輕鬆作弊。
解決方案
我整理了三種解決方案,可以根據實際情況選用。
1. 升級版本
目前 Apache 官方已經針對該漏洞釋出了補丁版本 2.15.0-rc2
,預設禁用了 lookup 行為,在確保升級該版本不會對專案的其他依賴產生衝突的情況下,建議升級。
該方案雖然比較簡單粗暴,但這個版本是否穩定?是否沒有漏洞呢?這很難說。
2. 修改引數
如果你不想升級 log4j 的版本,擔心會和專案其他依賴產生衝突的話,可以採用 Apache 官方推薦的臨時解決方案 —— 修改引數。
如果你的 log4j 版本 >= 2.10,可以通過設定系統屬性 log4j2.formatMsgNoLookups
或者環境變數 LOG4J_FORMAT_MSG_NO_LOOKUPS
為 true
來禁用 lookup 行為;如果版本在 2.0-beta9 到 2.10.0 之間, 可以直接移除從 classpath 中移除 JndiLookup
類,用以下命令即可:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
這個方案相對不容易引發專案的衝突,如果專案很緊急且重要,先用它處理吧。
3. 換框架
最暴力、也是解決最徹底的方案就是乾脆不用 log4j 了,用別的!
比如我自己很早之前就棄用 log4j,改用 logback 了,不說別的,logback 的測試更加充分,質量相對有保障一些。畢竟日誌框架作為一個專案必備的核心依賴,穩定性是至關重要的。
當然,這種方式對專案的影響可能會很大,如果一定要整體替換框架,建議進行充分的測試(覆蓋率越高越好),可不是改幾行程式碼那麼簡單。
最後魚皮再多說幾句吧,這次的事件又印證了軟體開發中的 不信任原則 ,沒有絕對可信、完全不出問題的服務,所以我們開發者要做的就是時刻多留一個心眼兒,儘量針對一些服務的不穩定去設計一些保護或降級措施。比如假設分散式快取會掛掉,可以再設計本地快取繼續提供臨時服務,保障系統的可用性。
不過還好這次漏洞對我沒什麼影響,一是專案本身沒用 log4j 而是 logback;二是在公司做的業務是內部系統,大多數基礎設施和中介軟體都是內網的,有網路層面的隔離保護;三是我自己的專案用到的服務也都是雲服務商提供的,哪怕出了問題,基本也不用自己解決(不過還是存在一定的安全風險就是了)。
唉,不知道有多少小夥伴週末要加班了,你躺槍了麼?
我是魚皮,原創不易,如果覺得文章還不錯,希望 點贊 支援下,謝謝大家~