防止asp.net页面在子文件夹中执行

时间:2012-11-02 19:57:28

标签: asp.net security iis iis-6

我有一个dotnet站点,其中包含一个虚拟目录(/ ArticleImages),该目录映射到另一台服务器上的文件共享。文件共享可供大量人员访问,因此,作为安全措施,我不希望在此文件夹中执行任何asp.net页面(例如,将default.aspx放入文件共享并浏览到site.com/ArticleImages /default.aspx要么不服务,要么最好是简单下载而不是执行。

我正在使用IIS 6.0并添加了虚拟目录。如果我从该文件夹中删除该应用程序,它将使用父应用程序并抱怨它无法读取web.config。如果我将应用程序添加到此文件夹,即使我删除了所有应用程序扩展,它也会抱怨svc-xyzzy(用于访问共享的帐户)无法访问“C:\ WINDOWS \ Microsoft.NET \ Framework \” v2.0.50727 \ Temporary ASP.NET Files'。

如何让应用程序的子文件夹不执行dotnet代码?

2 个答案:

答案 0 :(得分: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:Webforms

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);
}

注意您需要一种方法来获取MVC和Webforms(MIME Type Method From KodeSharp)的MIME类型

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;
} 

答案 1 :(得分: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>

但是如果他们可以删除它就没有用作代码。

相关问题