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

阻止asp.net页在子文件夹中执行,asp.net,security,iis,iis-6,Asp.net,Security,Iis,Iis 6,我有一个dotnet站点,它包含一个虚拟目录(/ArticleImages),映射到另一台服务器上的文件共享。很多人都可以访问该文件共享,因此,作为安全措施,我不希望在此文件夹中执行任何asp.net页面(例如,将default.aspx放入文件共享并浏览site.com/ArticleImages/default.aspx不应使用,或者最好作为简单下载而不是执行) 我正在使用IIS 6.0并添加了虚拟目录。如果我从此文件夹中删除该应用程序,它将使用父应用程序并抱怨它无法读取web.config

我有一个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代码的应用程序的子文件夹?

您可以在
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>


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

您可以在
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>


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

如果应用程序池运行的用户可以读取文件共享(默认情况下为网络服务),则可以完全删除虚拟目录,并创建一个ASP.NET应用程序,将文件流式传输到浏览器。如果您使用的是MVC,它只是返回一个文件结果。这还有一个额外的好处,即您可以限制用户下载文件。i、 e.您可以要求用户登录或具有下载文件的特定权限。还要确保您测试了路径遍历,您不会希望输入.././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类型


如果运行应用程序池的用户可以读取文件共享(默认情况下为网络服务),则可以完全删除虚拟目录,并创建一个ASP.NET应用程序,将文件流式传输到浏览器。如果您使用的是MVC,它只是返回一个文件结果。这还有一个额外的好处,即您可以限制用户下载文件。i、 e.您可以要求用户登录或具有下载文件的特定权限。还要确保您测试了路径遍历,您不会希望输入.././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类型


net被设置为根应用程序上的通配符处理程序,因此我必须在代码中构建某种过滤器,但我想它可以工作。不幸的是,他们将拥有对web.config选项的编辑/删除权限,这是不可行的。@Zarigani我键入的第一个解决方案将完成这项工作。.net被设置为根应用程序上的通配符处理程序,因此我必须在代码中构建某种过滤器,但我想它可以工作。不幸的是,他们将拥有对web.config选项的编辑/删除访问权限。这是不可行的。@Zarigani我键入的第一个解决方案将完成这项工作。如果.Net MVC>=4.5,您需要“MimeMapping.GetMimeMapping()”;如果.Net MVC>=4.5,您需要“MimeMapping.GetMimeMapping()”