【发布时间】:2010-11-13 19:27:26
【问题描述】:
有没有办法从 IIS7 中删除“服务器”响应标头?有一些文章表明使用 HttpModules 我们可以实现相同的目标。如果我们没有服务器的管理员权限,这将很有帮助。我也不想写 ISAPI 过滤器。
我对我的服务器拥有管理员权限。所以我不想做上面的事情。所以,请帮我做同样的事情。
【问题讨论】:
标签: security iis-7 header response
有没有办法从 IIS7 中删除“服务器”响应标头?有一些文章表明使用 HttpModules 我们可以实现相同的目标。如果我们没有服务器的管理员权限,这将很有帮助。我也不想写 ISAPI 过滤器。
我对我的服务器拥有管理员权限。所以我不想做上面的事情。所以,请帮我做同样的事情。
【问题讨论】:
标签: security iis-7 header response
将此添加到您的 global.asax.cs:
protected void Application_PreSendRequestHeaders()
{
Response.Headers.Remove("Server");
Response.Headers.Remove("X-AspNet-Version");
Response.Headers.Remove("X-AspNetMvc-Version");
}
【讨论】:
HttpContext.Current,您可能会发现您在 Cassini 中获得了 NullReferenceException。 This blog post 展示了如何在避免破坏 Cassini 支持的同时做到这一点,如果这对您很重要的话。
IHttpModule 或Global.asax 的类中使用PreSendRequestHeaders 不是一个好主意。我目睹了在压力负载下冻结服务器上的应用程序的事件。 BeginRequest 事件应该可以改变响应头。见hanselman.com/blog/ChecklistWhatNOTToDoInASPNET.aspx。
在 IIS7 中,您必须使用 HTTP 模块。在 VS 中将以下内容构建为类库:
namespace StrongNamespace.HttpModules
{
public class CustomHeaderModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += OnPreSendRequestHeaders;
}
public void Dispose() { }
void OnPreSendRequestHeaders(object sender, EventArgs e)
{
HttpContext.Current.Response.Headers.Set("Server", "Box of Bolts");
}
}
}
然后将以下内容添加到您的 web.config 中,或者您在 IIS 中配置它(如果您在 IIS 中配置,则程序集必须在 GAC 中)。
<configuration>
<system.webServer>
<modules>
<add name="CustomHeaderModule"
type="StrongNamespace.HttpModules.CustomHeaderModule" />
</modules>
</system.webServer>
</configuration>
【讨论】:
HttpApplication、HttpRequest、HttpContext 和 HttpResponse 是否不是 null,以及检查 HttpRequest.IsLocal是false。
PreSendRequestHeaders 中的标头可以cause issues with HttpCacheModule,您应该改用PostReleaseRequestState 之类的东西。
Scott Mitchell 在一篇博文中为removing unnecessary headers 提供了解决方案。
正如在其他答案中已经说过的,对于Server 标头,有http module solution 或web.config solution for IIS 10+,或者您可以使用URLRewrite instead for blanking it。
对于这个 Server 标头,最新 (IIS 10 +) 设置的最实用解决方案是在 web.config 中使用 removeServerHeader:
<system.webServer>
...
<security>
<requestFiltering removeServerHeader="true" />
</security>
...
</system.webServer>
对于X-AspNet-Version 和X-AspNetMvc-Version,Scott Mitchell 提供了一种比在每次响应中删除它们更好的方法:根本不生成它们。
在 web.config 中使用 enableVersionHeader 禁用 X-AspNet-Version
<system.web>
...
<httpRuntime enableVersionHeader="false" />
...
</system.web>
在 .Net Application_Start 事件中使用 MvcHandler.DisableMvcResponseHeader 来禁用 X-AspNetMvc-Version
MvcHandler.DisableMvcResponseHeader = true;
最后,在 IIS 配置中删除 web.config 中的 X-Powered-By 自定义标头。
<system.webServer>
...
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
...
</system.webServer>
请注意,如果您有 ARR(应用程序请求路由),它还会添加自己的 X-Powered-By,自定义标头设置不会将其删除。这个必须通过 IIS 管理器、IIS 根目录上的编辑器配置(不在站点上)删除:转到system.webServer/proxy 节点并将arrResponseHeader 设置为false。在IISReset 之后,将其考虑在内。
(我找到了这个here,除了这篇文章是关于旧的 IIS 6.0 的配置方式。)
不要忘记应用程序代码的解决方案默认情况下不适用于静态内容上生成的标头(您可以激活 runAllManagedModulesForAllRequests 来更改它,但它会导致所有请求运行 .Net 管道)。这对X-AspNetMvc-Version 来说不是问题,因为它没有添加到静态内容上(至少如果静态请求未在 .Net 管道中运行)。
旁注:当目的是隐藏使用过的技术时,您还应该更改标准 .Net cookie 名称(.ASPXAUTH 如果激活了表单身份验证(在 web.config 中的 forms 标签上使用 name 属性),@ 987654351@(在system.web标签下的web.config中使用<sessionState cookieName="yourName" />),__RequestVerificationToken(用AntiForgeryConfig.CookieName代码更改它,但不幸的是不适用于该系统在html中生成的隐藏输入)。
【讨论】:
Server 标头的 IIS 10+ 解决方案正上方的句子是关于它们的,链接到解决 IIS
启用 IIS 的 URL 重写模块版本 2.0 (UrlRewrite),在配置部分 <configuration> ➡ <system.webServer> ➡ <rewrite> 添加出站规则:
<outboundRules>
<rule name="Remove RESPONSE_Server" >
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
</outboundRules>
【讨论】:
system.webServer 中的rewrite 节点下。请注意,如果服务器上未安装 UrlRewrite,这将使您的站点崩溃。并且你最好先使用 IIS 配置控制台检查它是如何写下这些配置节点的。
实际上,上面显示的编码模块和 Global.asax 示例仅适用于有效请求。
例如,在您的 URL 末尾添加
显示的注册表设置也不起作用。 URLScan 是删除“服务器”标头的唯一方法(至少在 IIS 7.5 中)。
【讨论】:
此web.config 设置用于从 ASP.NET 响应中删除所有不必要的标头(至少从 IIS 10 开始):
<system.web>
<!-- Removes version headers from response -->
<httpRuntime enableVersionHeader="false" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<!--Removes X-Powered-By header from response -->
<clear />
</customHeaders>
</httpProtocol>
<security>
<!--Removes Server header from response-->
<requestFiltering removeServerHeader ="true" />
</security>
</system.webServer>
请注意,这会隐藏“应用程序”的所有标题,所有其他方法也是如此。如果你例如到达某些默认页面或由 IIS 本身或应用程序外部的 ASP.NET 生成的错误页面,这些规则将不适用。所以理想情况下,它们应该位于 IIS 的根级别,并且可能会给 IIS 本身留下一些错误响应。
附: IIS 10 中有一个bug,即使配置正确,它有时也会显示服务器标头。现在应该已经修复了,但是 IIS/Windows 必须更新。
【讨论】:
或者在web.config中添加:
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-AspNet-Version" />
<remove name="X-AspNetMvc-Version" />
<remove name="X-Powered-By" />
<!-- <remove name="Server" /> this one doesn't work -->
</customHeaders>
</httpProtocol>
</system.webServer>
【讨论】:
X-AspNet-Version和X-AspNetMvc-Version头的情况。我所知道的是这种方式并不总是有效的(如果它曾经有效的话)。请参阅@Frederic 答案以获取更可靠的删除它们的方法。
除了URL Rewrite answer,这里是web.config的完整XML
<system.webServer>
<rewrite>
<outboundRules>
<rule name="Remove RESPONSE_Server" >
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="Company name" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
【讨论】:
要删除Server: 标头,请转到Global.asax,查找/创建Application_PreSendRequestHeaders 事件并添加如下一行(感谢BK 和this blog 这在Cassini 上也不会失败/本地开发):
protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
// Remove the "Server" HTTP Header from response
HttpApplication app = sender as HttpApplication;
if (null != app && null != app.Request && !app.Request.IsLocal &&
null != app.Context && null != app.Context.Response)
{
NameValueCollection headers = app.Context.Response.Headers;
if (null != headers)
{
headers.Remove("Server");
}
}
}
如果您想要一个完整的解决方案来删除 Azure/IIS7 上的所有相关标头并且还可以使用 Cassini,请参阅this link,它显示了在不使用 HttpModules 或 URLScan 的情况下禁用这些标头的最佳方法。
【讨论】:
如果您只想删除标题,可以使用 lukiffer 答案的缩短版本:
using System.Web;
namespace Site
{
public sealed class HideServerHeaderModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders +=
(sender, e) => HttpContext.Current.Response.Headers.Remove("Server");
}
}
}
然后在Web.config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="CustomHeaderModule" type="Site.HideServerHeaderModule" />
</modules>
</system.webServer>
【讨论】:
尝试将HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\DisableServerHeader 注册表项设置为REG_DWORD 的1。
【讨论】:
OnPreSendRequestHeaders 事件处理程序(见上文)永远不会触发。
UrlScan 也可以通过在[options] 下使用AlternateServerName= 来删除服务器头。
【讨论】:
跟进eddiegroves' answer,根据 URLScan 的版本,您可能更喜欢RemoveServerHeader=1 下的[options]。
我不确定这个选项是在哪个版本的 URLScan 中添加的,但它在 2.5 及更高版本中可用。
【讨论】:
我发现一篇文章解释了为什么我们需要同时进行注册表编辑和使用 UrlScan 等工具在 IIS 中正确设置它。我在我们的服务器上跟踪它并且它有效:http://blogs.msdn.com/b/varunm/archive/2013/04/23/remove-unwanted-http-response-headers.aspx。如果您只使用 UrlScan 但不更改注册表,则在您停止 World Wide Publishing 服务期间,您的服务器将从 HTTP.sys 文件返回服务器 http 响应。另外,以下是使用 UrlScan 工具的常见误区:http://msdn.microsoft.com/en-us/library/ff648552.aspx#ht_urlscan_008
【讨论】:
在 IIS 10 中,我们使用了与 Drew 方法类似的解决方案,即:
using System;
using System.Web;
namespace Common.Web.Modules.Http
{
/// <summary>
/// Sets custom headers in all requests (e.g. "Server" header) or simply remove some.
/// </summary>
public class CustomHeaderModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += OnPreSendRequestHeaders;
}
public void Dispose() { }
/// <summary>
/// Event handler that implements the desired behavior for the PreSendRequestHeaders event,
/// that occurs just before ASP.NET sends HTTP headers to the client.
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void OnPreSendRequestHeaders(object sender, EventArgs e)
{
//HttpContext.Current.Response.Headers.Remove("Server");
HttpContext.Current.Response.Headers.Set("Server", "MyServer");
}
}
}
显然,在您的项目中添加对该 dll 的引用以及您想要的配置中的模块:
<system.webServer>
<modules>
<!--Use http module to remove/customize IIS "Server" header-->
<add name="CustomHeaderModule" type="Common.Web.Modules.Http.CustomHeaderModule" />
</modules>
</system.webServer>
重要说明1:此解决方案需要一个集成的应用程序池;
重要提示2:网络应用程序中的所有响应都将受此影响(包括css和js);
【讨论】:
我对此进行了研究,并且 URLRewrite 方法效果很好。似乎无法在任何地方很好地找到脚本的更改。我编写了与 PowerShell v2 及更高版本兼容的代码,并在 IIS 7.5 上对其进行了测试。
# Add Allowed Server Variable
Add-WebConfiguration /system.webServer/rewrite/allowedServerVariables -atIndex 0 -value @{name="RESPONSE_SERVER"}
# Rule Name
$ruleName = "Remove Server Response Header"
# Add outbound IIS Rewrite Rule
Add-WebConfigurationProperty -pspath "iis:\" -filter "system.webServer/rewrite/outboundrules" -name "." -value @{name=$ruleName; stopProcessing='False'}
#Set Properties of newly created outbound rule
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -filter "system.webServer/rewrite/outboundRules/rule[@name='$ruleName']/match" -name "serverVariable" -value "RESPONSE_SERVER"
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -filter "system.webServer/rewrite/outboundRules/rule[@name='$ruleName']/match" -name "pattern" -value ".*"
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -filter "system.webServer/rewrite/outboundRules/rule[@name='$ruleName']/action" -name "type" -value "Rewrite"
【讨论】:
您可以在 Global.asax.cs 文件中添加以下代码
protected void Application_PreSendRequestHeaders()
{
Response.Headers.Remove("Server");
}
【讨论】:
上面提出的解决方案通过以下更改对我有用。我在这里发布我的方案和解决方案。
对我来说,我想删除以下标题:
我将这些添加到我的 global.asax:
<%@ Application Language="C#" %>
<script runat="server">
protected void Application_PreSendRequestHeaders()
{
Response.Headers.Remove("Server");
Response.Headers.Remove("X-Powered-By");
Response.Headers.Remove("X-AspNet-Version");
Response.Headers.Remove("X-AspNetMvc-Version");
}
</script>
上述事件没有被触发,因此我在 web.config 中添加了以下内容。
<modules runAllManagedModulesForAllRequests="true" />
为了删除版本标头,我还在 web.config 中添加了以下内容:
<httpRuntime enableVersionHeader="false" />
web.config 的变化:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<system.web>
<httpRuntime enableVersionHeader="false" />
</system.web>
</configuration>
希望对你有帮助!
【讨论】:
我在这里和其他几个类似的堆栈溢出线程上尝试了所有的东西。
我有点挂断了,因为我在进行配置更改后忘记清除浏览器缓存。如果您不这样做并且该文件在您的本地缓存中,它将使用原始标头(duh)将其返回给您。
我主要是通过 删除 runAllManagedModulesForAllRequests:
<modules runAllManagedModulesForAllRequests="true">
这从 大多数 静态文件中删除了无关的标头,但我仍然在我的 WebAPI 项目中的一些静态文件上大摇大摆地获取“服务器”标头。
我终于找到并应用了这个解决方案,现在所有不需要的标题都消失了:
https://www.dionach.com/blog/easily-remove-unwanted-http-headers-in-iis-70-to-85
这里讨论了他的代码:
https://github.com/Dionach/StripHeaders/releases/tag/v1.0.5
这是一个本地代码模块。它能够删除 Server 标头,而不仅仅是空白值。默认情况下它会删除:
【讨论】:
IIS 7.5 和可能更新的版本将标题文本存储在 iiscore.dll
使用十六进制编辑器,找到字符串和后面的单词“Server”53 65 72 76 65 72,并将它们替换为空字节。在 IIS 7.5 中,它看起来像这样:
4D 69 63 72 6F 73 6F 66 74 2D 49 49 53 2F 37 2E 35 00 00 00 53 65 72 76 65 72
与其他一些方法不同,这不会导致性能损失。标头也会从所有请求中删除,甚至是内部错误。
【讨论】: