漏洞分析 Spring Framework路徑遍歷漏洞(CVE-2024-38816)

漏洞概述

VMware Spring Framework是美國威睿(VMware)公司的一套開源的Java、JavaEE應用程序框架。該框架可幫助開發人員構建高質量的應用。

近期,監測到Spring Framework在特定條件下,存在目錄遍歷漏洞(網宿評分:高危、CVSS 3.1 評分:7.5):

當同時滿足使用 RouterFunctions 和 FileSystemResource 來處理和提供靜態文件時,攻擊者可構造惡意請求遍歷讀取系統上的文件。

目前該漏洞POC狀態已在互聯網公開,建議客戶盡快做好自查及防護。

受影響版本

Spring Framework 5.3.0 - 5.3.39

Spring Framework 6.0.0 - 6.0.23

Spring Framework 6.1.0 - 6.1.12

其他更舊或者官方已不支持的版本

漏洞分析

根據漏洞描述(https://spring.io/security/cve-2024-38816)可知,關鍵變更在于如何處理靜態資源路徑。

https://github.com/spring-projects/spring-framework/commit/d86bf8b2056429edf5494456cffcb2b243331c49#diff-25869a3e3b3d4960cb59b02235d71d192fdc4e02ef81530dd6a660802d4f8707R4

這里改了兩處,分別是:

webflux --> org.springframework.web.reactive.function.server.PathResourceLookupFunction

webmvc --> org.springframework.web.servlet.function.PathResourceLookupFunction

它們都旨在為 Web 應用程序提供靜態內容的訪問。

以webmvc --> org.springframework.web.servlet.function.PathResourceLookupFunction為例,展開分析。

先是動態處理了資源請求,確保只返回有效并且可訪問的資源。

@Override
public Optional<Resource> apply(ServerRequest request) {PathContainer pathContainer = request.requestPath().pathWithinApplication();if (!this.pattern.matches(pathContainer)) {return Optional.empty();}pathContainer = this.pattern.extractPathWithinPattern(pathContainer);String path = processPath(pathContainer.value());if (path.contains("%")) {path = StringUtils.uriDecode(path, StandardCharsets.UTF_8);}if (!StringUtils.hasLength(path) || isInvalidPath(path)) {return Optional.empty();}try {Resource resource = this.location.createRelative(path);if (resource.isReadable() && isResourceUnderLocation(resource)) {return Optional.of(resource);}else {return Optional.empty();}}catch (IOException ex) {throw new UncheckedIOException(ex);}
}

接著對路徑字符串進行規范化處理,確保返回的路徑格式是有效的。

private String processPath(String path) {boolean slash = false;for (int i = 0; i < path.length(); i++) {if (path.charAt(i) == '/') {slash = true;}else if (path.charAt(i) > ' ' && path.charAt(i) != 127) {if (i == 0 || (i == 1 && slash)) {return path;}path = slash ? "/" + path.substring(i) : path.substring(i);return path;}}return (slash ? "/" : "");
}

最后從安全角度,確保路徑不指向敏感目錄,并且避免出現路徑穿越的情況。

private boolean isInvalidPath(String path) {if (path.contains("WEB-INF") || path.contains("META-INF")) {return true;}if (path.contains(":/")) {String relativePath = (path.charAt(0) == '/' ? path.substring(1) : path);if (ResourceUtils.isUrl(relativePath) || relativePath.startsWith("url:")) {return true;}}return path.contains("..") && StringUtils.cleanPath(path).contains("../");
}

簡單闡明以后,不難發現上述代碼做了敏感目錄檢查、url檢查、路徑穿越檢查等操作,暫時沒發現可疑點,所以我們需要進一步跟進

org.springframework.web.servlet.function.PathResourceLookupFunction#isInvalidPath()

查看一下它檢查相對路徑時,StringUtils.cleanPath()做了哪些操作。

public static String cleanPath(String path) {if (!hasLength(path)) {return path;}String normalizedPath;// Optimize when there is no backslashif (path.indexOf('\') != -1) {normalizedPath = replace(path, DOUBLE_BACKSLASHES, FOLDER_SEPARATOR);normalizedPath = replace(normalizedPath, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);}else {normalizedPath = path;}String pathToUse = normalizedPath;// Shortcut if there is no work to doif (pathToUse.indexOf('.') == -1) {return pathToUse;}// Strip prefix from path to analyze, to not treat it as part of the// first path element. This is necessary to correctly parse paths like// "file:core/../core/io/Resource.class", where the ".." should just// strip the first "core" directory while keeping the "file:" prefix.int prefixIndex = pathToUse.indexOf(':');String prefix = "";if (prefixIndex != -1) {prefix = pathToUse.substring(0, prefixIndex + 1);if (prefix.contains(FOLDER_SEPARATOR)) {prefix = "";}else {pathToUse = pathToUse.substring(prefixIndex + 1);}}if (pathToUse.startsWith(FOLDER_SEPARATOR)) {prefix = prefix + FOLDER_SEPARATOR;pathToUse = pathToUse.substring(1);}String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);// we never require more elements than pathArray and in the common case the same numberDeque<String> pathElements = new ArrayDeque<>(pathArray.length);int tops = 0;for (int i = pathArray.length - 1; i >= 0; i--) {String element = pathArray[i];if (CURRENT_PATH.equals(element)) {// Points to current directory - drop it.}else if (TOP_PATH.equals(element)) {// Registering top path found.tops++;}else {if (tops > 0) {// Merging path element with element corresponding to top path.tops--;}else {// Normal path element found.pathElements.addFirst(element);}}}// All path elements stayed the same - shortcutif (pathArray.length == pathElements.size()) {return normalizedPath;}// Remaining top paths need to be retained.for (int i = 0; i < tops; i++) {pathElements.addFirst(TOP_PATH);}// If nothing else left, at least explicitly point to current path.if (pathElements.size() == 1 && pathElements.getLast().isEmpty() && !prefix.endsWith(FOLDER_SEPARATOR)) {pathElements.addFirst(CURRENT_PATH);}final String joined = collectionToDelimitedString(pathElements, FOLDER_SEPARATOR);// avoid string concatenation with empty prefixreturn prefix.isEmpty() ? joined : prefix + joined;
}

這個方法主要對用戶輸入路徑做了規范化處理,具體包括長度檢查、不同操作系統下的路徑分隔符處理等。看起來也做了嚴格的處理,但這一步存在問題。

String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);

具體來說,它是允許空元素存在的,假設路徑字符串形如:

String pathToUse = “/static///…/…/Windows/win.ini”;

那么調用 delimitedListToStringArray 方法以后,pathArray即為

[“static”, “”, “”, “…”, “…”, “Windows”, “win.ini”]

而pathElements即為

再來看這一串:String pathToUse = “/static/…/…/Windows/win.ini”;

顯然,pathArray中存在空元素會影響上級目錄的處理,導致返回不同的結果,即存在安全隱患。

漏洞復現

實現目錄穿越需要用到"…/",結合上述分析,可通過這種方式實現。

package org.example.demo;

import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;

public class test {
public static void main(String[] args) {
String path = “/static///…/…/Windows/win.ini”;
System.out.println(isInvalidPath(path));
}

private static boolean isInvalidPath(String path) {
if (path.contains(“WEB-INF”) || path.contains(“META-INF”)) {
return true;
}
if (path.contains(“😕”)) {
String relativePath = (path.charAt(0) == ‘/’ path.substring(1) : path);
if (ResourceUtils.isUrl(relativePath) || relativePath.startsWith(“url:”)) {
return true;
}
}
return path.contains(“…”) && StringUtils.cleanPath(path).contains(“…/”);
}
}

但還需要結合上下文,繼續構造payload。首先路徑以斜杠開頭時,StringUtils.cleanPath()方法會去掉路徑的第個斜杠。

if (pathToUse.startsWith(FOLDER_SEPARATOR)) {prefix = prefix + FOLDER_SEPARATOR;pathToUse = pathToUse.substring(1);
}

那就需要多寫一條"/“,構造”///…/"跳一級目錄。

而在最初的org.springframework.web.servlet.function.PathResourceLookupFunction#apply()中,對路徑做了規范化處理,即去掉連續的"/"

pathContainer = this.pattern.extractPathWithinPattern(pathContainer);
String path = processPath(pathContainer.value());

所以需要將多余的"/“變為”",再借助StringUtils.cleanPath()方法重新轉換回來。

normalizedPath = replace(normalizedPath, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);

修復方案

目前官方已有可更新版本,建議受影響用戶升級至最新版本:

https://github.com/spring-projects/spring-framework/tags

產品支持

網宿全站防護-WAF已支持對該漏洞利用攻擊的防護,并持續挖掘分析其他變種攻擊方式和各類組件漏洞,第一時間上線防護規則,縮短防護“空窗期”。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895028.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895028.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895028.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

筆記:理解借貸相等的公式

強烈推薦非會計人士&#xff0c;快速了解會計看這個系列的視頻&#xff0c;其中比較燒腦的“借貸相等”公式&#xff0c;這個視頻講解的不錯&#xff1a; 4.小白財務入門-借貸記賬法_嗶哩嗶哩_bilibili 比如這里&#xff0c;錢在銀行卡重&#xff0c;所以銀行存款就是借方…

Java算法技術文章:深入解析排序、搜索與數據結構

引言 在軟件開發的世界里&#xff0c;算法不僅是程序設計的基礎&#xff0c;更是提升軟件性能、優化用戶體驗的關鍵。Java&#xff0c;作為一種廣泛使用的編程語言&#xff0c;提供了豐富的API和標準庫來支持各種算法的實現。本文將深入探討Java中的排序算法、搜索算法以及一些…

Android15音頻進階之MediaRecorder支持通道(一百零五)

簡介: CSDN博客專家、《Android系統多媒體進階實戰》一書作者 新書發布:《Android系統多媒體進階實戰》?? 優質專欄: Audio工程師進階系列【原創干貨持續更新中……】?? 優質專欄: 多媒體系統工程師系列【原創干貨持續更新中……】?? 優質視頻課程:AAOS車載系統+…

個人 Vite 構建性能分析插件開發實踐

Vite 構建分析插件開發實踐 一、開發背景 在個人項目開發中遇到以下問題&#xff1a; &#x1f552; 構建時間波動大&#xff08;30%&#xff09;&#x1f50d; 難以定位耗時模塊&#x1f4c8; 缺乏構建進度反饋 開發目標&#xff1a; 實現模塊級耗時分析提供實時進度預測識…

【Spring】什么是Spring?

什么是Spring&#xff1f; Spring是一個開源的輕量級框架&#xff0c;是為了簡化企業級開發而設計的。我們通常講的Spring一般指的是Spring Framework。Spring的核心是控制反轉(IoC-Inversion of Control)和面向切面編程(AOP-Aspect-Oriented Programming)。這些功能使得開發者…

學習筆記:機器學習中的數學原理(一)

1. 集合 集合分為有限集和無限集&#xff1b; 對于有限集&#xff0c;兩集合元素數相等即為等勢&#xff1b; 對于無限集&#xff0c;兩集合元素存在一一映射關系即為等勢&#xff1b; 無限集根據是否與正整數集等勢分為可數集和不可數集。 2. sigmoid函數&#xff08;也叫…

【信息系統項目管理師-案例真題】2016下半年案例分析答案和詳解

更多內容請見: 備考信息系統項目管理師-專欄介紹和目錄 文章目錄 試題一【問題1】4 分【問題2】12 分【問題3】3 分【問題4】6 分試題二【問題1】3 分【問題2】4 分【問題3】8 分【問題4】5 分【問題5】5 分試題三【問題1】4 分【問題2】8 分【問題3】5 分【問題4】8 分試題一…

基于javaweb的SpringBoothis智能醫院管理系統(源碼+文檔+部署講解)

&#x1f3ac; 秋野醬&#xff1a;《個人主頁》 &#x1f525; 個人專欄:《Java專欄》《Python專欄》 ??心若有所向往,何懼道阻且長 文章目錄 運行環境開發工具適用功能說明一、項目運行 環境配置&#xff1a; 運行環境 Java≥8、MySQL≥5.7、Node.js≥14 開發工具 后端&…

JS實現燈光閃爍效果

在 JS中&#xff0c;我們可以實現燈光閃爍效果&#xff0c;這里主要用 setInterval 和 clearInterval 兩個重要方法。 效果圖 源代碼 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>燈閃爍效果<…

Linux ltrace跟蹤入門

文章目錄 背景ltrace原理ltrace使用跟蹤程序調用庫函數跟蹤指定pid進程調用 參考 本文介紹ltrace跟蹤 背景 ltrace 會攔截并記錄正在執行的進程所調用的動態庫調用以及該進程接收到的信號&#xff0c;它還可以攔截并打印程序執行的系統調用。 其代碼位置在&#xff1a;https:/…

PCA9685 16路PWM 控制板 STM32F103 驅動

PCA9685 擁有16路PWM&#xff0c;通過 IIC 與 STM32 進行通信&#xff0c;以下驅動代碼已通過測試&#xff0c;你可以進行更多代碼優化 #include "pca9685.h"// 向 PCA9685 寫入一個字節數據 static void PCA9685_write8( uint8_t addr, uint8_t d) {while (I2C_Get…

使用 Apache Spark 進行大數據分析

使用 Apache Spark 進行大數據分析 環境準備 為了能夠在本地環境中運行Spark程序&#xff0c;需要先完成環境搭建。確保已經安裝了Jupyter Notebook和Apache Spark&#xff0c;并完成了兩者之間的集成。 創建 SparkSession 在 Python 中使用 PySpark 時&#xff0c;通常會創…

2025 專業的物聯網軟件開發公司有哪些

物聯網&#xff08;Internet of Things&#xff0c;簡稱IoT&#xff09;具有多個顯著的優勢&#xff0c;主要包括提高效率、節省成本、數據收集與分析、自動化控制、改善用戶體驗、增強決策能力和創新業務模式?。2025&#xff0c;有哪些比較專業的物聯網開發公司呢&#xff1f…

7.PPT:“中國夢”學習實踐活動【20】

目錄 NO1234? NO5678? NO9\10\11 NO1234 考生文件夾下創建一個名為“PPT.pptx”的新演示文稿Word素材文檔的文字&#xff1a;復制/挪動→“PPT.pptx”的新演示文稿&#xff08;藍色、黑色、紅色&#xff09; 視圖→幻燈片母版→重命名&#xff1a;“中國夢母版1”→背景樣…

學習筆記十九:K8S生成pod過程

K8S生成pod過程 流程圖具體生成過程用戶提交 Pod 定義API Server 處理請求調度器分配節點&#xff08;Scheduling&#xff09;目標節點上的 Pod 創建網絡配置狀態上報與監控控制器管理&#xff08;Controller Manager&#xff09;就緒與服務發現 關鍵錯誤場景高級特性 流程圖 具…

封裝descriptions組件,描述,靈活

效果 1、組件1&#xff0c;dade-descriptions.vue <template><table><tbody><slot></slot></tbody> </table> </template><script> </script><style scoped>table {width: 100%;border-collapse: coll…

21.2.6 字體和邊框

版權聲明&#xff1a;本文為博主原創文章&#xff0c;轉載請在顯著位置標明本文出處以及作者網名&#xff0c;未經作者允許不得用于商業目的。 通過設置Rang.Font對象的幾個成員就可以修改字體&#xff0c;設置Range.Borders就可以修改邊框樣式。 【例 21.6】【項目&#xff…

FPGA VGA timing

概念 VGA(Video Graphics Array)時序是控制VGA接口顯示圖像的關鍵參數,它主要包括行時序和場時序兩部分。以下是對VGA時序的詳細解釋: 一、VGA接口簡介 VGA接口是IBM公司在1987年推出的一種使用模擬信號的視頻傳輸標準,具有成本低、結構簡單、應用靈活等優點,至今仍被廣…

中級通信工程師綜合教材(5、6章節)

五、現代通信網 1、通信網的構成要素 通信網在硬件設備方面的構成要素是交換設備、傳輸鏈路和終設備。 構成要素 功能作用 常見設備舉例 終端設備 通信的源點和目的地 電話機、傳真機、計算機、視頻終端、多媒體終端等 交換設備 通信網的核心設備,主要完成呼叫處理、信令處理…

360手機刷機 360手機解Bootloader 360手機ROOT

360手機刷機 360手機解Bootloader 360手機ROOT 問&#xff1a;360手機已停產&#xff0c;現在和以后&#xff0c;能刷機嗎&#xff1f; 答&#xff1a;360手機&#xff0c;是肯定能刷機的 360手機資源下載網站 360手機-360手機刷機RootTwrp 360os.top 360rom.github.io 一、…