【Java代碼審計 | 第八篇】文件操作漏洞成因及防范

未經許可,不得轉載。

文章目錄

  • 文件操作漏洞
    • 文件讀取漏洞
      • 基于 InputStream 的讀取
      • 基于 FileReader 的讀取
    • 文件下載漏洞
    • 文件刪除漏洞
    • 防范

在這里插入圖片描述

文件操作漏洞

分為文件讀取漏洞、文件下載漏洞與文件刪除漏洞。

文件讀取漏洞

在Java中,文件讀取通常有兩種常見方式:一種是基于InputStream,另一種是基于FileReader

漏洞成因:未對用戶輸入做過濾,導致讀取敏感文件并返回至客戶端。

以下兩種代碼形式都存在路徑遍歷問題。

基于 InputStream 的讀取

String filename = request.getParameter("filename");  // 假設這是用戶輸入的文件名
File file = new File(filename);  // 創建文件對象,未進行任何路徑驗證
InputStream inputStream = new FileInputStream(file);  // 創建輸入流
int len;
while (-1 != (len = inputStream.read())) {  // 循環讀取文件內容outputStream.write(len);  // 將讀取的字節寫入輸出流
}

基于 FileReader 的讀取

String filename = request.getParameter("filename");  // 假設這是用戶輸入的文件名
String fileContent = "";  // 存儲文件內容
FileReader fileReader = new FileReader(filename);  // 創建FileReader對象,未進行任何路徑驗證
BufferedReader bufferedReader = new BufferedReader(fileReader);  // 包裝為BufferedReader
String line;
while (null != (line = bufferedReader.readLine())) {  // 逐行讀取文件fileContent += (line + "\n");  // 拼接每一行內容
}

文件下載漏洞

漏洞成因:未對用戶輸入做過濾,導致用戶端可下載敏感文件。

filename 參數未經過任何驗證或過濾,攻擊者可以通過構造惡意路徑下載系統敏感文件。

String filename = request.getParameter("filename");  // 獲取文件名
File file = new File(filename);  // 創建文件對象
response.reset();  // 重置響應
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("utf-8")));  // 設置下載文件名
response.addHeader("Content-Length", "" + file.length());  // 設置文件大小
response.setContentType("application/octet-stream; charset=utf-8");  // 設置響應內容類型為二進制流InputStream inputStream = new FileInputStream(file);  // 創建輸入流讀取文件
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());  // 獲取輸出流
int len;
while (-1 != (len = inputStream.read())) {  // 讀取文件并寫入響應outputStream.write(len);
}
inputStream.close();  // 關閉輸入流
outputStream.close();  // 關閉輸出流

文件刪除漏洞

漏洞成因:未對用戶輸入做過濾,導致敏感文件被刪除。

filename 參數未經過任何驗證或過濾,攻擊者可以通過構造惡意路徑刪除系統關鍵文件。

String filename = request.getParameter("filename");  // 獲取文件名
File file = new File(filename);  // 創建文件對象
if (file != null && file.exists() && file.delete()) {  // 檢查文件存在并刪除response.getWriter().println("Delete success");  // 刪除成功
} else {response.getWriter().println("Delete failed");  // 刪除失敗
}

防范

1、使用 getCanonicalPath() 方法獲取文件的規范路徑,并與預期的基路徑進行比較,確保文件路徑在允許的范圍內。

String basePath = "/allowed/directory/";  // 允許訪問的基路徑
File file = new File(basePath, filename);  // 拼接文件路徑
if (!file.getCanonicalPath().startsWith(new File(basePath).getCanonicalPath())) {throw new SecurityException("非法文件路徑");  // 路徑不在允許范圍內,拋出異常
}

對以下語句進行解讀:

if (!file.getCanonicalPath().startsWith(new File(basePath).getCanonicalPath())) {

file.getCanonicalPath():這個方法返回文件的規范化路徑,即將路徑中的 .(當前目錄)和 …(上級目錄)等符號解析成實際的絕對路徑。

1、假設:basePath = “/allowed/directory/”
2、用戶輸入 filename = “…/…/etc/passwd”
3、new File(basePath):創建 /allowed/directory/ 的 File 對象。
4、file = new File(basePath, filename):用戶提供的路徑是 …/…/etc/passwd,所以拼接后的 file 實際路徑為 /allowed/directory/…/…/etc/passwd,這是一個潛在的路徑遍歷。
5、file.getCanonicalPath():獲取文件的規范化路徑,經過解析后變為 /etc/passwd(因為路徑 …/…/ 會使路徑跳轉到根目錄)。
6、new File(basePath).getCanonicalPath():獲取 /allowed/directory/ 的規范化路徑,即 /allowed/directory/。
7、在這種情況下,file.getCanonicalPath()(即 /etc/passwd)不會以 /allowed/directory/ 開頭,因此會進入 if 語句塊,阻止訪問該文件。

其次是檢查文件后綴是否在允許的后綴白名單中,舉個例子:

// 定義允許的文件后綴白名單
Set<String> allowedExtensions = new HashSet<>(Arrays.asList("txt", "pdf", "jpg", "png", "doc", "xls"
));String filename = request.getParameter("filename");  // 獲取文件名
String fileExtension = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();  // 提取后綴并轉為小寫// 檢查后綴是否在白名單中
if (!allowedExtensions.contains(fileExtension)) {throw new SecurityException("非法文件類型");  // 文件類型不在白名單中,拋出異常
}File file = new File(filename);  // 創建文件對象// 使用 try-with-resources 讀取文件
try (InputStream inputStream = new FileInputStream(file);OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {int len;while (-1 != (len = inputStream.read())) {outputStream.write(len);}
} catch (IOException e) {e.printStackTrace();
}

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

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

相關文章

與rkipc通信

rkipc的通信方式 在ipcweb中&#xff0c;程序是通過/var/tmp/rkipc和rkipc進行通信&#xff0c;并且網絡和客戶端的函數封裝在luckfox-pico/project/app/ipcweb/ipcweb-backend/src/socket_client文件夾中&#xff0c; client.cpp是客戶端命令 socket.cpp是網絡命令 編寫rkip…

NLP常見任務專題介紹(2)-多項選擇任務(MultipleChoice)訓練與推理模板

一、 使用 BigBird 進行多項選擇任務訓練與推理 本示例展示如何使用 BigBirdForMultipleChoice 訓練一個多項選擇模型,適用于考試答題、閱讀理解、常識推理等任務。 1?? 任務描述 目標:給定一個問題和多個選項,模型預測正確答案。 數據格式:輸入包含 (問題, 選項1, 選項…

【論文解讀】MODEST 透明物體 單目深度估計和分割 ICRA 2025

MODEST是一種用于透明物體的單目深度估計和分割的方法&#xff0c;來自ICRA 2025。 它通過單張RGB圖像作為輸入&#xff0c;能夠同時預測透明物體的深度圖和分割掩碼。 由深度圖生成點云數據&#xff0c;然后采用GraspNet生成抓取位姿&#xff0c;開展透明物體抓取實驗。 論文…

【網絡安全工程】任務11:路由器配置與靜態路由配置

目錄 一、概念 二、路由器配置 三、配置靜態路由CSDN 原創主頁&#xff1a;不羈https://blog.csdn.net/2303_76492156?typeblog 一、概念 1、路由器的作用&#xff1a;通過路由表進行數據的轉發。 2、交換機的作用&#xff1a;通過學習和識別 MAC 地址&#xff0c;依據 M…

深入理解隱式類型轉換:從原理到應用

C?持內置類型隱式類型轉換為類類型對象&#xff0c;需要有相關內置類型為參數的構造函數。 構造函數前?加explicit就不再?持隱式類型轉換。 類類型的對象之間也可以隱式轉換&#xff0c;需要相應的構造函數?持。 內置類型隱式類型轉換為類類型對象 在 C 中&#xff0c;如果…

垃圾收集算法與收集器

在 JVM 中&#xff0c;垃圾收集&#xff08;Garbage Collection, GC&#xff09;算法的核心目標是自動回收無用對象的內存&#xff0c;同時盡量減少對應用性能的影響。以下是 JVM 中主要垃圾收集算法的原理、流程及實際應用場景的詳細介紹&#xff1a; 一、標記-清除算法&#…

如何為服務設置合理的線程數

1. 首先&#xff0c;要確定最大線程數的限制因素。通常&#xff0c;線程數量受限于內存、CPU和操作系統限制。比如&#xff0c;每個線程都需要一定的棧內存&#xff0c;默認情況下Java線程的棧大小是1MB&#xff08;64位系統可能更大&#xff09;&#xff0c;所以如果內存不足&…

內容中臺:元數據驅動管理新范式

元數據驅動智能管理中樞 現代企業內容管理正經歷從碎片化存儲向結構化治理的范式轉變&#xff0c;元數據驅動機制在此過程中展現出核心樞紐價值。通過構建多維屬性標簽體系&#xff0c;Baklib等內容中臺解決方案實現了對文本、音視頻等數字資產的精準定義&#xff0c;其動態分…

在mac中設置環境變量

步驟一&#xff1a;打開終端 步驟二&#xff1a;輸入printenv&#xff0c;查看當前已有的環境變量&#xff1b; 步驟三&#xff1a;輸入&#xff1a;nano ~/.zshrc 打開環境變量編輯頁面&#xff1b; 步驟四&#xff1a;輸入新的變量&#xff1a;export DEEPSEEK_API_KEY&qu…

擴散模型的算法原理及其在圖像生成領域的優勢與創新

目錄 一、引言 二、擴散模型的加噪過程 &#xff08;一&#xff09;前向擴散過程 &#xff08;二&#xff09;噪聲調度策略 三、擴散模型的去噪過程 &#xff08;一&#xff09;反向擴散過程 &#xff08;二&#xff09;去噪網絡架構 四、擴散模型的訓練和推理機制 &am…

技術領域,有許多優秀的博客和網站

在技術領域&#xff0c;有許多優秀的博客和網站為開發者、工程師和技術愛好者提供了豐富的學習資源和行業動態。以下是一些常用的技術博客和網站&#xff0c;涵蓋了編程、軟件開發、數據科學、人工智能、網絡安全等多個領域&#xff1a; 1. 綜合技術博客 1.1 Medium 網址: ht…

mysql經典試題共34題

1、準備數據 -- drop drop table if exists dept; drop table if exists emp; drop table if exists salgrade;-- CREATE CREATE TABLE dept (deptno int NOT NULL COMMENT 部門編號,dname varchar(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMM…

2025 - GDB 盲調筆記--調試 “無調試符號“ “無調試信息“ 的三方程序

環境&#xff1a; arm64-ubuntu 相關&#xff1a;strace、ltrace、readelf、patchelf、strings、ldd -v 1). 使用 gdb 啟動目標程序(不能直接用gdb啟動的&#xff0c;可以先單獨啟動&#xff0c;再 gdb attach 強制調試) DIR_APP/opt/test gdb --args env LANGUAGE LD_LIBRA…

OCPP擴展機制與自定義功能開發:協議靈活性設計與實踐 - 慧知開源充電樁平臺

OCPP擴展機制與自定義功能開發&#xff1a;協議靈活性設計與實踐 引言 OCPP作為開放協議&#xff0c;其核心價值在于平衡標準化與可擴展性。面對不同充電樁廠商的硬件差異、區域能源政策及定制化業務需求&#xff0c;OCPP通過**擴展點&#xff08;Extension Points&#xff09…

【項目】nnUnetv2復現

作者提出一種nnUNet(no-new-Net)框架,基于原始的UNet(很小的修改),不去采用哪些新的結構,如相殘差連接、dense連接、注意力機制等花里胡哨的東西。相反的,把重心放在:預處理(resampling和normalization)、訓練(loss,optimizer設置、數據增廣)、推理(patch-based…

代碼隨想錄算法訓練營第八天|Leetcode 151.翻轉字符串里的單詞 卡碼網:55.右旋轉字符串 字符串總結 雙指針回顧

151.翻轉字符串里的單詞 建議&#xff1a;這道題目基本把 剛剛做過的字符串操作 都覆蓋了&#xff0c;不過就算知道解題思路&#xff0c;本題代碼并不容易寫&#xff0c;要多練一練。 題目鏈接/文章講解/視頻講解&#xff1a;代碼隨想錄 我們這道題的思路是&#xff0c;先將整…

【計算機網絡】計算機網絡的性能指標——時延、時延帶寬積、往返時延、信道利用率

計算機網絡的性能指標 導讀 大家好&#xff0c;很高興又和大家見面啦&#xff01;&#xff01;&#xff01; 在上一篇內容中我們介紹了計算機網絡的三個性能指標——速率、帶寬和吞吐量。用大白話來說就是&#xff1a;網速、最高網速和實時網速。 相信大家看到這三個詞應該就…

Refreshtoken 前端 安全 前端安全方面

網絡安全 前端不需要過硬的網絡安全方面的知識,但是能夠了解大多數的網絡安全,并且可以進行簡單的防御前兩三個是需要的 介紹一下常見的安全問題,解決方式,和小的Demo,希望大家喜歡 網絡安全匯總 XSSCSRF點擊劫持SQL注入OS注入請求劫持DDOS 在我看來,前端可以了解并且防御前…

vue3框架的響應式依賴追蹤機制

當存在一個響應式變量于視圖中發生改變時會更新當前組件的所以視圖顯示&#xff0c;但是沒有視圖中不寫這個響應式變量就就算修改該變量也不會修改視圖&#xff0c;這是為什么&#xff1f;我們能否可以理解寬泛的理解為vue組件的更新就是視圖的更新&#xff0c;單當視圖中不存在…

C#核心(22)string

前言 我們在之前的學習中已經學習過了很多數字類型的數據結構,但一直沒有講解除了char以外的字符串相關的知識點,這也是我們繼繼承,封裝,重載這些知識點之后要補充講解的核心知識點。 你也發現了,其實在密封函數之后我們就已經開始進入更底層的方面為你講解知識點了,這…