【摘要】 程式中如果使用未經校驗的輸入構造 SpEL 語句,就有可能造成 SpEL 表達式注入漏洞,對下遊服務可能産生惡意攻擊。本文介紹了 SpEL 表達式以及常見的 SpEL 注入攻擊,詳細地介紹了部分漏洞攻擊執行個體以及常用的漏洞檢測與防禦手段。
在安全角度來看外部來源的資料,均應視為不可信資料,對外部資料,其包含的所有資訊都須經過校驗或者過濾,再向下遊服務進行傳遞。若無防護手段,攻擊者可以通過構造惡意輸入,對服務進行攻擊。程式中如果使用未經校驗的輸入構造 SpEL 語句,就有可能造成 SpEL 表達式注入漏洞。部分 SpEL 表達式注入漏洞 CVSS3.x 評分極高,nvd 認定為高危漏洞,具有高緻命性。
1SpEL表達式介紹
Spring 表達式語言(Spring Expression Language,SpEL)是 Spring Framework 的核心技術之一,其支援在運作時查詢和操作對象圖。SpEL 文法類似于 Unified Expression Language,但提供了更加豐富的功能,最特别的是方法調用與字元串模闆功能。SpEL 主要支援以下功能:
• 文字表達式
• 布爾和關系運算符
• 正規表達式
• 類表達式
• 通路 properties, arrays, lists, maps
• 方法調用
• 關系運算符
• 參數
• 調用構造函數
• Bean 引用
• 構造 Array
• 内嵌 lists
• 内嵌 maps
• 三元運算符
• 變量
• 使用者定義的函數
• 集合投影
• 集合篩選
• 模闆表達式
SpEL 功能強大,可以操作類和方法。
• 引用方法:dog.run()
• 引用靜态方法:T(java.lang.Math).PI
• 類執行個體化:使用 new 執行個體化對象,類名必須是全限定名,java.lang 包内的除外如 Integer、String 等
• 變量定義及指派引用
在解析 SpEL 之後,擷取表達式結果時,可以指定表達式的上下文對象:EvaluationContext
• (預設)StandardEvaluationContext:支援全套 SpEL 語言和功能配置選項,功能強大但存在隐患
• SimpleEvaluationContext:僅支援 SpEL 文法的子集,不包括 Java 類型引用,構造函數和 bean 引用,功能相對簡單但是安全
2SpEL表達式注入漏洞
曆史報告的大部分 SpEL 漏洞大多涉及不受信任的使用者輸入的情況,惡意攻擊者可能利用 SpEL 實作任意代碼執行、拒絕服務等攻擊,與 SpEL 相關的部分 CVE 漏洞見表 1。
表 1 部分 SpEL 注入 CVE 漏洞
CVE ID | 概述 | 評分 cvss3.x |
CVE-2022-22963 | 在 Spring Cloud Function 相關版本,存在 SpEL 表達式注入。惡意攻擊者無需認證可通過構造特定的 HTTP 請求頭注入 SpEL 表達式,最終執行任意指令,擷取伺服器權限。 | 9.8 |
CVE-2022-22980 | Spring Data for MongoDB 是 Spring Data 項目的一部分,該項目旨在為新的資料存儲提供熟悉和一緻的基于 Spring 的程式設計模型,同時保留存儲的特定特征和功能。Spring Data MongoDB 應用程式在對包含查詢參數占位符的 SpEL 表達式使用 @Query 或 @Aggregation 注解的查詢方法進行值綁定時,如果輸入未被過濾,則容易受到 SpEL 注入攻擊。 | 9.8 |
CVE-2018-1273 | Spring Data Commons, 1.13 至 1.13.10、2.0 至 2.0.5 之前的版本以及不支援的舊版本包含一個屬性綁定器漏洞,該漏洞是由特殊元素的無效化導緻的。未經身份驗證的遠端惡意使用者(或攻擊者)可以針對 Spring Data REST 支援的 HTTP 資源提供特制的請求參數,進而導緻遠端代碼執行攻擊。 | 9.8 |
CVE-2021-45029 | Groovy 代碼注入和 SpEL 注入,導緻遠端代碼執行。此問題影響 Apache shenyu 2.4.0 和 2.4.1。 | 9.8 |
CVE-2022-22950 | Spring Framework 版本 5.3.0 - 5.3.16 和較早的不支援版本,使用者可以提供可能導緻拒絕服務條件的巧盡心思建構的 SpEL 表達式。 | 6.5 |
CVE-2016-4977 | 當使用 Spring Security OAuth 2.0.0 至 2.0.9 和 1.0.0 至 1.0.5 中的白标簽視圖(whitelabel views)處理授權請求時,response_type 參數值作為 Spring SpEL 執行,這使得惡意使用者能夠通過建立 response_type 值來觸發遠端代碼執行。 | 8.8 |
常見的 SpEL 注入攻擊流程如圖 1 所示,漏洞的基本條件有: 使用 StandardEvaluationContext,2. 未對輸入的 SpEL 進行校驗,3. 對表達式調用了 getValue () 或 setValue () 方法。當滿足上述條件時,就給了攻擊者可乘之機。
圖 1 常見的 SpEL 注入攻擊流程
3漏洞執行個體
3.1CVE-2022-22963 Spring Cloud FunctionSpEL注入漏洞
3.1.1基本資訊
漏洞 id | CVE-2022-22963 |
漏洞簡介 | 在 Spring Cloud Function 相關版本,存在 SpEL 表達式注入。惡意攻擊者無需認證可通過構造特定的 HTTP 請求頭注入 SpEL 表達式,最終執行任意指令,擷取伺服器權限。 |
漏洞釋出位址 | |
漏洞安全級别 | 高 |
漏洞代碼倉位址 | |
漏洞更新檔送出位址 | |
漏洞影響包版本 | 3.0.0 <= Spring Cloud Function <= 3.2.2 |
3.1.2Spring Cloud Function介紹
Spring Cloud Function 是基于 Spring Boot 的函數計算架構。它提供了一個通用的模型,用于在各種平台上部署基于函數的軟體,包括像 Amazon AWS Lambda 這樣的 FaaS(函數即服務,function as a service)平台。該項目緻力于促進函數為主的開發單元,它抽象出所有傳輸細節和基礎架構,并提供一個通用的模型,用于在各種平台上部署基于函數的軟體。
3.1.3CVE-2022-22963漏洞攻擊路徑
使用 spring-cloud-function-web 的 Spring boot 應用,通過設定 Message Headers 來傳達路由指令,也可以在請求頭中指定 spring.cloud.function.definition 或 spring.cloud.function.routing-expression 作為應用程式屬性,允許使用 Spring 表達式語言。
當在 application.properties 中設定 spring.cloud.function.definition=functionRouter 進而将預設路由綁定具體函數由使用者進行控制。
攻擊者調用 /functionRouter 接口,并在請求頭的 spring.cloud.function.routing-expression 中使用攻擊性的 SpEL 語句,服務端就會解析 SpEL 并執行。
漏洞攻擊圖示如圖 2 所示。
圖 2 CVE-2022-22963 漏洞攻擊路徑
3.1.4CVE-2022-22963漏洞修複方式
該漏洞主要從四處進行了修複,(1)聲明一個 SimpleEvaluationContext,專用作來自 header 的 SpEL 的解析 ;(2)新增一個布爾變量 isViaHeader,用于标記目前 Expression 是否來自 Header;(3)如果是從 Header 中擷取的 spring.cloud.function.routing-expression 表達式,isViaHeader 為 true ;(4)isViaHeader 為 true 時,expression.getValue 指定使用 headerEvalContext。如圖 3 所示。
圖 3 CVE-2022-22963 漏洞修複
3.2CVE-2022-22980 Spring DataMongoDBSpEL表達式注入漏洞
3.2.1基本資訊
漏洞 id | CVE-2022-22980 |
漏洞簡介 | Spring Data for MongoDB 是 Spring Data 項目的一部分,該項目旨在為新的資料存儲提供熟悉和一緻的基于 Spring 的程式設計模型,同時保留存儲的特定特征和功能。Spring Data MongoDB 應用程式在對包含查詢參數占位符的 SpEL 表達式使用 @Query 或 @Aggregation 注解的查詢方法進行值綁定時,如果輸入未被過濾,則容易受到 SpEL 注入攻擊。 |
漏洞釋出位址 | |
漏洞安全級别 | 高 (CVSS3.x: 9.8) |
漏洞代碼倉位址 | |
漏洞更新檔送出位址 | 3.3.x https://github.com/spring-projects/spring-data-mongodb/commit/7c5ac764b343d45e5d0abbaba4e82395b471b4c4 3.4.x https://github.com/spring-projects/spring-data-mongodb/commit/5e241c6ea55939c9587fad5058a07d7b3f0ccbd3 |
漏洞影響包版本 | Spring Data MongoDB == 3.4.0 3.3.0 <= Spring Data MongoDB <= 3.3.4 其他不維護的老版本 |
漏洞時間線 |
3.2.2Spring Data forMongoDB介紹
Spring Data for MongoDB 是 Spring Data 的一個子子產品。 目标是為 MongoDB 提供一個相近的一緻的基于 Spring 的程式設計模型。其核心功能是映射 POJO 到 Mongo 的 DBCollection 中的文檔,并且提供 Repository 風格資料通路層。主要特性有:
• Spring 配置支援:使用基于 Java 的 @Configuration 類或基于 XML 命名空間的配置來驅動 Mongo 執行個體和副本
• MongoTemplate 輔助類:可提高執行常見 Mongo 操作的效率,包括文檔和 POJO 之間的內建對象映射
• 異常處理:異常轉換為 Spring 的可移植的資料通路異常層次結構
• 功能豐富的對象映射與 Spring 的轉換服務內建
• 基于注釋的映射中繼資料、并且可擴充以支援其他中繼資料格式
• 持久化和映射生命周期事件
• 使用 MongoReader/MongoWriter 抽象的低級映射
• 基于 Java 的查詢、條件和更新 DSL
• Repository 接口的自動實作,包括對自定義查詢方法的支援
• QueryDSL 內建以支援類型安全的查詢,以及地理空間整合
• Map-Reduce 內建
• JMX 管理和監控
• 對存儲庫的 CDI 支援
• GridFS 支援
3.2.3CVE-2022-22980漏洞攻擊路徑
圖 4 CVE-2022-22980 漏洞攻擊路徑
3.2.4CVE-2022-22980複現
1) 實驗代碼:learnjavabug
2) 運作服務,com.threedr3am.bug.spring.data.mongodb.Application#main
3) Postman 發送請求,如圖 5 所示
圖 5 Postman 填寫參數示例
4) 現象:電腦程式被執行
3.2.5CVE-2022-22980修複方式
Spring Data for MongoDB 在修複此漏洞時,重新實作 evaluator,指定 EvaluationContext 類型,如圖 6 所示。
圖 6 CVE-2022-22980 修複方式
4檢測與防禦手段
(1)對于 SpEL 表達式注入漏洞漏洞,可以使用靜态分析工具進行代碼檢查,可以有效規避部分問題。
(2)在此類場景中,對于使用者輸入,應當仔細校驗,檢查使用者輸入的合法性,保障其内容為正常資料。且在端側與服務側均應對使用者資料進行校驗,對非受信使用者輸入資料進行淨化,避免使用者輸入任意内容。
(3)及時更新 Spring Framework 版本,避免因版本老舊而被利用的問題發生。
(4)使用源碼靜态分析工具進行白盒自動化檢測,在代碼合入階段、靜态分析監控階段及時發現相關問題。
文章來自 PaaS 技術創新 Lab,PaaS 技術創新 Lab 隸屬于華為雲,緻力于綜合利用軟體分析、資料挖掘、機器學習等技術,為軟體研發人員提供下一代智能研發工具服務的核心引擎和智慧大腦。我們将聚焦軟體工程領域硬核能力,不斷構築研發利器,持續傳遞高價值商業特性!加入我們,一起開創研發新 “境界”!(詳情歡迎聯系 [email protected];[email protected])
PaaS 技術創新 Lab 首頁連結:https://www.huaweicloud.com/lab/paas/home.html