如何重命名 Trace.axd?
在 ASP.NET 中将 Trace.axd 重命名为自定义名称
引言
跟踪是 ASP.NET 中一个出色的诊断功能,它是一个非常有用的工具,可以用于调试 ASP.NET 应用程序,尤其是在我们无法调试应用程序的生产服务器上。跟踪在运行时收集诊断信息,例如页面执行流程、请求信息、自定义跟踪消息以及其他诊断信息,以调试应用程序。基本上,它将收集到的信息附加到页面或跟踪查看器(Trace.axd)内容中。不利的一面是,跟踪通过向外部世界公开应用程序的所有基本信息而引入了高度的漏洞安全风险,因此黑客可以使用这些信息并进行攻击。这是我们被建议在生产服务器上停止跟踪的原因之一(它也对性能有影响)。
Trace.axd 是一个用于访问跟踪查看器的虚拟硬编码资源,在应用程序安全领域中,它以信息泄露而闻名。当 Web 应用程序上启用了跟踪时,黑客可以使用这个 trace.axd 来收集信息。另一个问题是,我们无法将 Trace.axd 重命名为自定义名称,并且 ASP.NET 中不存在直接的选项。我找到了一些有趣的步骤来重命名 Trace.axd,在本文中,我们将逐步了解如何在 ASP.NET 中将 Trace.axd 重命名为自定义资源名称。
先决条件
我假设您对 ASP.NET 跟踪、HTTP 处理程序和模块概念有所了解。了解响应过滤器会更好,但不是强制性的。如果您对上述项目不了解,请不用担心,只需阅读以下链接,然后返回此处以更好地理解。
背景
在 ASP.NET 中,所有与动态资源相关的请求都由相应的 HTTP 处理程序处理,同样,跟踪查看器请求(Trace.axd)由 System.Web
命名空间中的 TraceHandler
处理。有了这些信息,我们可以在 web.config 中添加处理程序配置,为 Trace.axd 指定一个替代名称。但问题并未完全解决,因为跟踪处理程序会将 Trace.axd 引用注入到超链接中,因此当用户点击这些超链接时,它将导航到 Trace.axd。如您所知,我们无法直接修改跟踪处理程序的内容,因此除非我们创建自己的跟踪处理程序,否则我们无法从跟踪查看器输出中替换 Trace.axd 引用,但幸运的是,ASP.NET 中有一个名为 响应过滤器 的选项,它可以在发送到浏览器之前更改响应。响应过滤器是流的专用版本,它具有读取和写入响应内容的选项。
重命名 Trace.axd
通过使用 HTTP 处理程序/模块和响应过滤器概念,我们将模拟 Trace.axd 的重命名,这需要以下五个步骤
- 启用跟踪
- 阻止对 Trace.axd 的访问
- 为 Trace.axd 配置一个替代名称
- 创建响应过滤器
- 注册响应过滤器
下图解释了 ASP.NET 应用程序中智能跟踪查看器的生命周期。
启用跟踪
我假设您已经在 web.config 中启用了跟踪选项。由于这是其他步骤的先决条件,我希望确保您已经完成。如果没有,请在 web.config 中添加以下配置。
<system.web>
<trace enabled="true" localOnly="false"
pageOutput="false" requestLimit="500"
mostRecent="true" traceMode="SortByTime"/>
</system.web>
根据您的需求更改以上设置。
阻止对 Trace.axd 的访问
只要启用了跟踪,我们就可以从外部世界访问 Trace.axd,因此我们需要阻止对 Trace.axd 的访问,就像 web.config 在 Web 服务器中被阻止一样。我们可以通过在 web.config 中简单地添加以下配置来对 Trace.axd 执行相同的操作。
<system.webserver>
<security>
<requestfiltering>
<hiddensegments>
<add segment="Trace.axd"></add>
</hiddensegments>
</requestfiltering>
</security>
</system.webserver>
上述设置不适用于 ASP.NET 开发服务器,因此我们需要将解决方案部署到 IIS7 或更高版本才能进行测试。
当我们在 web.config 中添加上述配置后,尝试从本地 IIS 服务器访问 Trace.axd 时,它将返回以下错误消息。
当我们尝试从远程机器访问 Trace.axd 时,它将返回以下消息
为 Trace.axd 配置一个替代名称
下一步,我们需要指定自定义名称来访问跟踪查看器,为此,请在 web.config 中添加以下配置。在这里,我将 Eventviewer.aspx 作为 Trace.axd 的替代资源,您可以随意命名。
<system.web>
<httpHandlers>
<add verb="GET,POST" path="Eventviewer.aspx"
validate="false" type="System.Web.Handlers.TraceHandler,
System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</httpHandlers>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<handlers>
<add name="SmartTraceHandler" path="Eventviewer.aspx"
verb="GET,POST" type="System.Web.Handlers.TraceHandler, System.Web,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</handlers>
</system.webServer>
现在,您可以通过 eventviewer.aspx 访问跟踪查看器,但我们知道,eventviewer
页面的内容在超链接中仍然引用 Trace.axd。在下一节中,我们将看到如何解决这个问题。
创建响应过滤器
幸运的是,ASP.NET 中有响应过滤器,可以在将响应发送到浏览器之前对其进行修改,我们将使用此响应过滤器将所有超链接中的 Trace.axd 替换为自定义资源名称。响应过滤器是 stream
类的专用形式,它覆盖了 stream
类的几个重要方法和属性,以读取和写入响应内容。在这里,我创建了一个名为 TraceFilter
的响应过滤器,它有一个重写的 Write
方法来查找和替换所有 Trace.axd 引用。以下代码片段显示了 TraceFilter
的 Write
方法。
public override void Write(byte[] buffer, int offset, int count)
{
var content = _encoding.GetString(buffer, offset, count);
// Find all trace.axd entries and replace it with custom resource name
var checkTrace = new Regex("Trace.axd", RegexOptions.IgnoreCase);
if (checkTrace.IsMatch(content)) {
content = checkTrace.Replace(content, TraceFile);
buffer = _encoding.GetBytes(content);
}
// write back the modified response
_stream.Write(buffer, 0, buffer.Length);
}
注册响应过滤器
现在,我们需要将新的响应过滤器附加到响应上下文中,但没有简单的方法可以做到(不像在 web.config 中添加 HTTP 处理程序/HTTP 模块配置那样)。为了做到这一点,我们需要创建一个 HTTP 模块并将其附加到相应的响应上下文。在这里,我创建了一个名为 SmartTraceModule
的 HTTP 模块,它将检查与自定义资源相关的请求并将我们的响应过滤器附加到响应中。
public class SmartTraceModule : IHttpModule
{
/// <summary>
/// Initialize the custom trace module
/// </summary>
/// <param name="context"></param>
public void Init(HttpApplication context)
{
//Make sure the current request is related to ASP.NET
//dynamic pages and it's already processed with respective handler
context.ReleaseRequestState += new EventHandler(InstallTraceFilter);
}
/// <summary>
/// Installs the trace filter to current response stream
/// when the current request to smart trace viewer and content type in text/html
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void InstallTraceFilter(object sender, EventArgs e)
{
var context = HttpContext.Current;
var response = context.Response;
//install the trace filter when the current request
//to smart trace viewer and content type is text/html
if (context.Request.RawUrl.ToLower().EndsWith(TraceFilter.TraceFile)
&& response.ContentType == "text/html")
response.Filter = new TraceFilter(response.Filter,response.ContentEncoding);
}
/// <summary>
/// Clean all used resources here
/// </summary>
public void Dispose() {
}
}
最后,我们需要将 SmartTraceModule
配置到 web.config 中,如下所示
<system.web>
<httpModules>
<add name="SmartTraceModule" type="SmartTrace.SmartTraceModule, SmartTrace"/>
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<add name="SmartTraceModule" type="SmartTrace.SmartTraceModule, SmartTrace"/>
</modules>
</system.webServer>
现在,我们已准备好使用自定义名称(在本例中为 eventviewer.aspx)访问跟踪查看器。要使用附加的示例项目进行测试,请执行以下步骤
- 下载附加的源代码并使用 Visual Studio 2010 或更高版本打开解决方案。
- 生成并运行应用程序。它将在您的默认浏览器中打开 https://:53927/ URL,您将看到以下屏幕
- 点击屏幕上显示的所有按钮以生成一些跟踪数据。然后键入 URL https://:53927/eventviewer.aspx 以查看跟踪查看器,您将获得以下跟踪查看器屏幕。
在这里,我们成功地以新名称(eventviewer.aspx)而不是 Trace.axd 获得了跟踪查看器。由于我们没有更改跟踪查看器的任何功能,它将像以前一样工作。在这里,您可以点击“查看详细信息”链接以导航到详细信息视图。
正如我们所预期的,新资源名称(eventviewer.aspx)已通过我们的响应过滤器添加到详细信息页面 URL。
结论
在本文中,我们了解了如何将 Trace.axd 重命名为自定义资源名称,但这并不是一个解决安全问题的万无一失的解决方案,事实上,它通过修改响应内容引入了一点性能影响(需要额外的步骤才能从响应内容中重命名 Trace.axd)。将跟踪查看器公开访问存在高漏洞风险,因此应限制授权人员并进行适当的身份验证。在生产服务器上停止跟踪总是更好的选择(为了提高性能和安全性),但在不可避免的情况下,您可以使用此选项。感谢您阅读本文,希望它能为您提供一些有用的信息。请提供您对本文的宝贵反馈。