1

我有一个 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\临时 ASP.NET 文件'。

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

4

2 回答 2

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:网络表单

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 类型(来自 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;
} 
于 2012-11-03T06:17:26.380 回答
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>

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

于 2012-11-02T22:26:05.067 回答