2009-11-18 127 views
3

我有一個asp.net mvc應用程序,其路線允許用戶請求存儲在Web應用程序目錄之外的文件。如何確保文件路徑在C#中安全?

我只是告訴你它最終將它們限制在一個他們有權訪問的安全目錄中,從而簡化了這個場景。

例如:

如果用戶(其ID爲100)請求:

http://mysite.com/Read/Image/Cool.png 

然後我的應用程序將要追加 「Cool.png」 到「C:\ ImageRepository \ Users \用戶100「並將這些字節寫入響應。工作進程有權訪問此路徑,但匿名用戶不能。我已經有這個工作。

但將一些惡意用戶能夠請求是這樣的:

http://mysite.com/Read/Image/..\101\Cool.png 

並將其解析爲

"C:\ImageRepository\Customers\101\Cool.png" 

(其他一些用戶的形象?)

或者類似的東西那?有沒有辦法確保路徑是乾淨的,這樣用戶被限制到他們自己的目錄?

+0

我不認爲「http://mysite.com/Read/Image/..\101\Cool。 PNG「將與ASP.NET MVC路線一起工作,如果你有正確的設置。你應該做的是確保你的動作查找用戶ID「101」的文件夾,然後在該文件夾中查找圖像「Cool.png」,而不是將所有輸入附加到特定文件夾路徑,這本質上是用戶輸入注入。 – Omar 2009-11-18 01:10:56

+1

是不是請求URI'http://mysite.com/Read/Image/ .. \ 101 \ Cool.png'在它之前被清理爲'http:// mysite.com/Read/101/Cool.png'通過將URI路由到asp.net-mvc中的處理程序的機制解釋? – dtb 2009-11-18 01:13:43

+0

未知 - 我想過,但我需要支持http://mysite.com/Read/Image/Favorites/Randy/Cool.png等合法請求。 dtb - 我只是平原不知道。看起來我的例子不起作用(好!),但我更一般地詢問這類攻擊中的東西,我甚至沒有想到。 – Chris 2009-11-18 01:25:51

回答

4

如何

​​

這應該確保你只能得到一個簡單的文件名。

+0

我將立即閱讀這些方法,並在Linqpad中與他們一起玩。我有一個預感,這是正確的方向。 – Chris 2009-11-18 01:23:27

+0

每當我亂入輸入時,都會拋出異常,所以我認爲這是要走的路。 – Chris 2009-11-18 02:12:16

0

也許你應該驗證路徑是從用戶的目錄路徑開始的?

例如"C:\ImageRepository\Customers\100\"

在比較路徑時,還應將路徑標準化爲大寫字母。

+2

那麼C:\ ImageRepository \ Customers \ 100 \ .. \ 101 \ secretstuff.png怎麼樣? – 2009-11-18 01:12:29

+0

他應該首先將路徑解析爲最簡單的形式,然後驗證路徑是否以正確的路徑作爲前綴。 – 2009-11-18 01:17:19

+0

好的,也許是Tor的答案和.StartsWith()建議的結合? – Chris 2009-11-18 01:22:55

0

最安全的方法是,如果它是一個選項(您正在使用Windows身份驗證),則通過在文件夾上使用Active Directory權限使其成爲非問題,因此無論用戶嘗試訪問目錄無效。

如果沒有,請存儲文件以便從用戶提取路徑。也就是說,使用用戶提供的任何名稱作爲具有文件的實際路徑的表中的查找。

Cannolocalization保護是棘手的業務,嘗試和超出潛在的攻擊者是危險的。

+0

不幸的是,這個程序是註定要上網的。 – Chris 2009-11-18 01:22:20

+0

這意味着什麼,到底是什麼? – JohnFx 2009-11-18 02:30:34

0

使用Request.MapPath超載是檢查這一個辦法:

try 
{ 
    string mappedPath = Request.MapPath(inputPath.Text,         Request.ApplicationPath, false); 
} 
catch (HttpException) 
{ 
    // do exception handling 
} 

你也可能爆炸的字符串,並用斜槓分隔它,並檢查用戶名比賽也。

0

爲了也能夠在路徑中包含子目錄,你可以使用:

string SafeCombine(string basePath, string path) 
{ 
    string testPath = Path.GetFullPath(Path.Combine(basePath, path)); 
    if (testPath.startsWith(basePath)) 
     return testPath; 
    throw new InvalidOperationException(); 
}