2012-11-02 24 views
1

我有一個dotnet網站,其中包含映射到另一臺服務器上的文件共享的虛擬目錄(/ ArticleImages)。文件共享可以被大量的人訪問,所以作爲一種安全措施,我不希望任何asp.net頁面在這個文件夾中執行(例如,將default.aspx放入文件共享中並瀏覽到site.com/ArticleImages /default.aspx或者不能提供服務,或者最好是簡單的下載而不是執行)。防止asp.net頁面在子文件夾中執行

我使用IIS 6.0並添加了虛擬目錄。如果我從這個文件夾中刪除應用程序,它會使用父應用程序,並抱怨它無法讀取web.config。如果我將一個應用程序添加到此文件夾中,即使我刪除了所有應用程序擴展,它也會抱怨svc-xyzzy(用於訪問共享的帳戶)無法訪問'C:\ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ Temporary ASP.NET Files'。

如何獲得不執行dotnet代碼的應用程序的子文件夾?

回答

1

如果文件共享是通過你的應用程序池下(網絡服務默認情況下)運行,您可以完全刪除虛擬目錄,並創建一個ASP.NET應用程序,將文件流式傳輸到瀏覽器的用戶讀取。如果你使用MVC,它只是返回一個文件結果。這有一個額外的好處,你將能夠限制用戶下載文件。即您可以要求用戶登錄或具有下載文件的特定權限。另外請確保您測試路徑遍歷,您不希望用戶輸入../../filename來下載他們不被允許的文件。

選項1:ASP.NET MVC

public ActionResult Download(string file) 
{ 
    // Check for directory traversal attack 
    if(file.IndexOf('\\') > -1 || file.IndexOf('/') > -1) 
    { 
     return new HttpNotFoundResult(); 
    } 

    file = System.IO.Path.Combine("\\FILE_SHARE_FOLDER\\", file); 

    if(!System.IO.File.Exists(file)) 
    { 
     return new HttpNotFoundResult();     
    } 

    return this.File(file, GetMimeType(file)); 
} 

選項2:Web表單

private void DownloadFile(string file) 
{ 
    // Check for directory traversal attack 
    if(file.IndexOf('\\') > -1 || file.IndexOf('/') > -1) 
    { 
     Response.StatusCode = 404; 
     Response.End(); 
    } 

    file = System.IO.Path.Combine("\\FILE_SHARE_FOLDER\\", file); 

    if (!System.IO.File.Exists(file)) 
    { 
     Response.StatusCode = 404; 
     Response.End(); 
    } 

    Response.ContentType = GetMimeType(file); 
    Response.TransmitFile(file); 
} 

注意您將需要一個方法來獲得MIME類型都MVC和Webforms(MIME Type Method From KodeSharp

private string GetMimeType(string fileName) 
{ 
    string mimeType = "application/unknown"; 
    string ext = System.IO.Path.GetExtension(fileName).ToLower(); 
    Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext); 
    if (regKey != null && regKey.GetValue("Content Type") != null) 
     mimeType = regKey.GetValue("Content Type").ToString(); 
    return mimeType; 
} 
0

您可以在global.asax檢查請求,並且如果從你不能讓目錄來,然後停止處理爲:

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    string cTheFile = HttpContext.Current.Request.Path; 

    if(cTheFile.StartsWith("/articleimages", StringComparison.CurrentCultureIgnoreCase) 
    { 
     HttpContext.Current.Response.TrySkipIisCustomErrors = true; 
     HttpContext.Current.Response.Write("Please start from home page"); 
     HttpContext.Current.Response.StatusCode = 403; 
     HttpContext.Current.Response.End(); 
     return ; 
    } 
} 

當然,你可以簡單的地方一個額外web.config上的目錄與這裏面:

<configuration> 
    <system.web> 
     <authorization> 
     <deny users="*" /> 
     </authorization> 
    </system.web> 
</configuration> 

但如果他們可以刪除它沒有用的代碼。

+0

.net被設置爲根應用程序上的通配符處理程序,因此我必須在代碼中構建某種過濾器,但我想它可以工作。不幸的是,他們將不得不編輯/刪除對web.config選項的訪問。 – Zarigani

+0

@Zarigani我有類型的第一個解決方案將完成這項工作。 – Aristos