作者 | Erik Costlow
編譯 | 核子可樂、冬梅
Log4j2 漏洞會拖垮 Java?胡扯!
12 月 10 日淩晨,Apache 開源項目 Log4j 的遠端代碼執行漏洞細節被公開,由于 Log4j 的廣泛使用,該漏洞一旦被攻擊者利用會造成嚴重危害。
Log4j 是一個被許多 Java 應用程式使用的庫,它是迄今為止最普遍的 Java 庫之一。Log4j 安全問題圍繞 Log4j 庫中的一個錯誤展開,該錯誤可能允許攻擊者在使用 Log4j 寫出日志消息的系統上執行任意代碼。這個安全漏洞影響廣泛,該漏洞一旦被攻擊者利用會造成嚴重危害。
随着 Log4j 安全漏洞問題的持續發酵,一些天天唱衰 Java 的家夥,又開始借助這一漏洞問題将矛頭指向 Java。他們總愛發文發帖、強調這種已經擁有 25 年曆史的頂級程式設計語言就快不行了。不過每次 Java 都能挺過來,繼續為全球無數開發者服務。這裡我先要承認,不少安全廠商針對 log4j2 漏洞利用原理釋出的文章确實意義重大。這個安全問題确實值得大家保持關注,也推薦各位盡快根據建議審查自己的 Java 項目是否存在隐患。
在本文中,我想着重聊聊 Java 生态系統,探讨日志記錄架構是什麼、為什麼 / 該怎麼使用這些架構,以及開發團隊要如何觀察并控制自己 JVM 的活動模式。
Java 開發者們的安全責任
Java 開發者們應該如何保證安全性?答案很簡單——隻要快速修複 JDK 和庫,我們就能規避大多數潛在的普遍性違規問題。
修複庫(必選)
一旦發現庫記憶體在漏洞,最有效的方法當然是修複庫以消除漏洞。若不及時修複,你的應用程式很可能被黑客入侵,攻擊者将獲得對目标系統及其資料的完全通路權限。
而無論面對什麼狀況,修複都是最有效的應對手段。
日志架構可以來自任何依賴項——既可以是傳遞依賴項(由其他庫添加),也可以是直接依賴項(由你自己添加)。我們可以使用 Contrast Community Edition 等分析工具檢查目前依賴項及其他自定義漏洞。
此外,Maven dependency tree (dependency:tree) 與 Gradle dependency tree 也都是很好的開源依賴項分析工具。NetBeans 等 IDE 則提供依賴項關系圖可視化工具。隻要更新至 2.15.0 或更高版本,log4j2 漏洞就不會再騷擾各位。
按照 Java 安全基準(推薦、定期)修複 JRE
各個 Java 主版本都會維護一套持續性的安全基準。由于 JDK 每個季度都會通過新一輪安全改進實施修複,是以這套基準也在持續前進。換言之,任何低于目前安全基準的 Java 安裝包都包含某些已知安全問題,應立即進行更新。
當然,這隻是标準的安全最佳實踐,與 log4j2 庫漏洞沒有直接關系、也解決不了這個漏洞。
但開發團隊仍然應該使用 Foojay Disco API 自動監控安全基準并更新現有系統。開發人員可以将其與 GitHub 操作比對起來,確定代碼中的每個 build 都切實引入了最新安全更新。而一旦安全事件出現,更新 JRE 與代碼的重構與重新部署也将同步進行。
Java 安全基準會在每年 1 月、4 月、7 月和 10 月最靠近 17 号的那個星期二迎來更新。詳細資訊請參考 Oracle 重要更新檔更新計劃,具體方式與 OpenJDK 漏洞組保持相同。當然,有時候即使沒有大問題、官方也可能提供計劃外的安全更新。Log4j2 并不屬于此類。
下面我們以 Java 11 中的安全基準配置為例:
定期檢測自定義安全漏洞(測試中,推薦)
自動化安全工具能幫助我們在缺乏相關知識時仍準确捕捉到安全漏洞。通過将內建代理添加至 Java 應用程式當中,大家即可對應用程式中記錄的安全資訊進行被動檢測。與前文提到的分析依賴項編号以确定是否存在漏洞的工具不同,這些自動化安全工具雖然也會跟蹤同樣的依賴項資訊,但會通過內建分析器告知各現有庫間的組合效果、特别是配合使用是否安全。
例如,內建分析器并不會簡單檢視是否存在 log4j2 漏洞及其版本,而是檢測遠端輸入記錄功能是否會被攻擊者所控制。
此外,Contrast Community Edition 等免費分析工具也能捕捉 log4j2 零日漏洞及其他多種安全缺陷的行蹤,例如:
我的應用程式中是否包含 SQL 注入缺陷,例如在 Hibernate、JBDC 或者其他位置?
遠端攻擊者能否控制發送至 Runtime.exec 的任何輸入,進而導緻指令注入漏洞?
我的應用程式中使用到哪些加密算法,具體用在何處、是否符合适當的安全标準?
我們是否正以某種非正常、有風險的方式組合不同庫,例如 OGNL 輸入解析?
使用 JDK Flight Recorder 監控安全事件
JDK Flight Recorder 是各類現代 OpenJDK 發行版中普遍提供的性能分析工具,能夠以低資源成本提供安全資訊。開發團隊可以使用 JDK Flight Recorder 記錄下諸多 IO 操作,例如 JRE 通路過哪些檔案、或者哪些類與反序列化配對。
通過使用 JDK Flight Recorder 監控 Java 應用程式事件,并将事件流傳輸至安全資訊與事件管理(SIEM)系統當中,Java 團隊即可監控異常行為并 / 或是将已知安全類同 Java 反序列化過濾器相配對,是以防止漏洞利用行為。
以 log4j2 場景為例,Web 應用程式防火牆(WAF)等類似的網絡防禦方案雖然在短期内會有一定效果,但整體表現不佳而且工作量極為巨大。
網絡防禦成效捉急。大家可能都聽過網上流傳的段子,有人用 Photoshop 精心設計出一張看似正常、似藏玄機的車牌,識别系統一掃就會遭遇注射攻擊。這辦法絕了,因為開發者知道車牌識别系統會嘗試解析和記錄一切通過計算機視覺捕捉到的内容,而且這部分注入資料壓根不用經過網絡層。同樣的,大多數應用程式也會有針對性地使用部分資料、解碼資料并記錄下各類細節。很明顯,任何網絡工具都沒辦法覆寫到如此廣泛的攻擊面。
監控并跟蹤攻擊者,第一時間屏蔽其 IP 同樣效果不佳。雖然有些組織會堅持維護一套潛在攻擊者清單,但 AWS IP 之是以被命名為 Elastic(彈性),正是因為它們會定期更改。即使拉黑一個,對方要麼可以等自然解禁、要麼就是換個 IP 繼續攻擊。
系統屬性與動态更新檔:效果尚可
我們可以使用幾個系統屬性與更新檔控制住 log4j2 的肆意活動。如果暫時無法更新庫或者依賴項,那這些就是最合理的過渡性安全問題。
兩項 Java 系統屬性:
另有一個動态更新檔能夠接入目前運作的 JVM 并執行修複。它的問題是,我們每次啟動 JVM 都需要再次運作此更新檔。在一部分用例中這樣就夠了,隻是肯定不如直接更新庫來得友善。
Java 是如何處理日志記錄的?
Java 開發者通常會從多種日志記錄系統和外觀中做出選擇。随着社群的多年發展、合并和交融,各類日志記錄架構往往已經能夠彼此協同運作:
System Logger (2017 年,推薦) 在 JDK 9 中被首次引入。它改進了 JDK Logger 的 API,并提供類似于 SLF4j 的外觀,能夠将 JDK 日志重新定向至應用程式團隊指定的記錄器處。
JDK Logger (2004 年) 于 Java 1.4 版本中被引入。它特别常見,隻是 API 顯得有點陳舊了。雖然也能用,但不像其他日志記錄架構那麼靈便。
Log4j 與 Log4j2 屬于社群開發的記錄器。它們改進了 API,讓團隊能夠輕松控制需要記錄的内容、檢索特定資料何時出現在哪些層級。
Logback 與 SLF4j 也是兩款頗具人氣的記錄器。SLF4J 屬于一套相對簡單的日志記錄外觀,可幫助團隊管理其他多種記錄器——庫維護人員将直接登入到 SLF4J,之後再由應用程式開發人員具體配置要使用哪些底層記錄器提供統一的輸出結果。除了高品質 AIP 之外,二者還最大限度減少了我們需要面對的依賴項。
JBoss Logger 是 JBoss 生态系統中的另一款流行記錄器,運作狀态穩定且速度很快。它現在已經能夠支援 Quarkus 等多種其他日志記錄架構。
Apache Commons-Logging(2002 年)的曆史比 JDK Logger 更長,也啟發了後來諸多 API。它的最後一個版本釋出于 2014 年,之後随着從單一項目向跨項目 API 的使用者趨勢變化而沒落。
對于依賴項較少、釋出時間不長的新興項目,這裡建議大家優先考慮 System Logger。對于包含大量依賴項的項目,我們則建議繼續遵循大部分依賴項的對接的既有記錄器、或者使用統一的日志記錄外觀(門面)。
如果你之前并沒有使用任何記錄器,則可以把 System Logger 當成是具有良好 API 的 JDK Logger 來使用。
參考連結:
https://www.infoworld.com/article/3644492/how-to-detect-the-log4j-vulnerability-in-your-applications.html
https://foojay.io/today/log4j-isnt-killing-java/