在 C# 中可以這樣組合路徑:
兩個的結果都是:
上面的程式碼是假設有一個預設路徑 rootPath ,要在裡面儲存檔案,檔名是變數 fileName ,兩者組合後產生 path ,fullPath 就是這個檔案實際的路徑。
但是如果將 fileName 換成 "../../../Program.cs" ,結果如下:
就會發現明明已經指定預設的路徑(資料夾),但是還是可以存取預設路徑外的其他任何路徑的檔案。
代表將「檔名」交給使用者或是外部控管是有風險的,這就是很常見的 Broken Access Control - Path Manipulation 漏洞。
而要解決也很簡單,只是這個動作在不了解的人面前會看起來很多餘,就是檢查「檔案完整路徑」的開頭和預設路徑是否一致:
如果不放心還可以再加上忽略大小寫比對:
var rootPath = @"C:\Users\ruyut\Documents\Projects\ConsoleAppPathTest";
var fileName = "Program.cs";
var path = Path.Combine(rootPath, fileName);
Console.WriteLine(path);
var fullPath = Path.GetFullPath(path);
Console.WriteLine(fullPath);
兩個的結果都是:
C:\Users\ruyut\Documents\Projects\ConsoleAppPathTest\Program.cs
上面的程式碼是假設有一個預設路徑 rootPath ,要在裡面儲存檔案,檔名是變數 fileName ,兩者組合後產生 path ,fullPath 就是這個檔案實際的路徑。
但是如果將 fileName 換成 "../../../Program.cs" ,結果如下:
// Path.Combine(rootPath, fileName)
C:\Users\ruyut\Documents\Projects\ConsoleAppPathTest\../../../Program.cs
// Path.GetFullPath(path)
C:\Users\ruyut\Program.cs
就會發現明明已經指定預設的路徑(資料夾),但是還是可以存取預設路徑外的其他任何路徑的檔案。
代表將「檔名」交給使用者或是外部控管是有風險的,這就是很常見的 Broken Access Control - Path Manipulation 漏洞。
而要解決也很簡單,只是這個動作在不了解的人面前會看起來很多餘,就是檢查「檔案完整路徑」的開頭和預設路徑是否一致:
var rootPath = @"C:\Users\ruyut\Documents\Projects\ConsoleAppPathTest";
var fileName = "../../../Program.cs";
var path = Path.Combine(rootPath, fileName);
Console.WriteLine(path);
var fullPath = Path.GetFullPath(path);
if (!fullPath.StartsWith(rootPath))
throw new Exception("Invalid path");
Console.WriteLine(fullPath);
如果不放心還可以再加上忽略大小寫比對:
var rootPath = @"C:\Users\ruyut\Documents\Projects\ConsoleAppPathTest";
var fileName = "../../../Program.cs";
var path = Path.Combine(rootPath, fileName);
Console.WriteLine(path);
var fullPath = Path.GetFullPath(path);
if (!fullPath.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
throw new Exception("Invalid path");
Console.WriteLine(fullPath);
感謝分享~
回覆刪除