[英]How to validate a file path in java?
我正在編寫一個Java程序,該程序從用戶讀取一些輸入,這些輸入應該是預定義文件夾的相對路徑。 例如,他將輸入test / subfolder,而我將生成/path/to/test/subfolder
。
我如何檢查並防止用戶輸入../../../
東西,會弄亂路徑並允許他訪問不允許的路徑?
在Java 7+中,使用Path
對象,可以在創建最終路徑之前調用normalize()
方法。 該方法將通過消除..
和前面的路徑段來規范化路徑,並消除任何.
段。
有幾種情況需要考慮。 例如,如果提供的路徑是相對的
../first/second
在這種情況下,規范化無法刪除..
因為它不知道之前的內容。 您要做的就是在root /
上解析此路徑。 例如
Path path = Paths.get("../first");
path = Paths.get("/").resolve(path.normalize()).normalize();
路徑可以以任意數量的..
開始。
Path path = Paths.get("../../../../first/../second/../../more");
path = Paths.get("/").resolve(path.normalize()).normalize();
該過程將連續應用。
在某些情況下,提供的路徑也是絕對的。 在這種情況下,您可以立即將其標准化。
Path path = Paths.get("/../../../../first/../second/../../more").normalize();
然后,您可以根據前綴路徑解析提供的路徑(請注意,如果提供的路徑是絕對路徑)。
對於其他人提出的符號鏈接,請在使用java.nio.Files
時繼續將NIO與java.nio.file.LinkOption.NOFOLLOW_LINKS
使用。
為了更加一致,我讓他寫他想要的內容,並在他選擇允許的路徑后檢查(允許選擇的File並檢查其路徑)。 他可能會找到您沒有想到的方法,例如別名。
此外(盡管如此),如果您希望界面易於使用並通知他在選擇路徑時已經禁止使用該界面,請使用正則表達式檢查輸入路徑中是否存在../(或簡單地執行pathString.indexOf( "../" ) == -1
檢查)
我之前曾嘗試過這個問題。 如果使用以下方法將預定義文件夾與路徑合並
new Path(basePath, givenRelativePath);
那么我什么都不知道,除了..
會導致結果超出baseDir的范圍 (當然, 前提是沒有指向外部的符號鏈接)。 因此,最簡單的檢查是檢測兩個連續點的存在,就像丹尼爾斯建議的那樣。
如果您想絕對確定(並處理符號鏈接或其他潛在危險的事情),則可以檢查以下結果(僅是草圖):
if (givenPath.indexOf("..") >= 0)
throw new IllegalArgumentException();
File result = new File(basePath, givenPath);
if (!result.getCanonicalPath().startsWith(basePath.getCanonicalPath()))
throw new IllegalArgumentException();
serveFile(result);
這基本上是我幾個月前結束的事情。
當然,在Java 7+中,您可以使用Path
和normalize
方法來代替getCanonicalPath
,這是更快的並且不會影響文件系統。 另一方面,它不考慮符號鏈接和其他內容。
如果您確實要忽略用戶輸入,則以“。”形式鍵入相對路徑。 或“ ..”,您可以嘗試這個。. 在此處輸入鏈接說明
File f = new File("/../../../../path/to/folder"); // Wrong user input
Path path = f.toPath();
String str1 = path.normalize().toString(); // ouout -> /path/to/folder
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.