Remove Server from HTTP Response in WCF

陌路散爱 提交于 2019-12-01 05:36:00

问题


I have an internet exposed WCF service running on IIS 7.5 that I need to secure. I would like to remove the "Server" header in the HTTP response.

I've implemented an IDispatchMessageInspector with code as follows.

public void BeforeSendReply(ref Message reply, object correlationState)
{
    var context = WebOperationContext.Current;
    if (context != null)
    {
        context.OutgoingResponse.Headers.Remove(
            HttpResponseHeader.Server);
    }
}

However, the Server header is still in the response. On debugging I can see that the OutgoingResponse.Headers does not include HttpResonseHead.Server, and if I write my own value it is clearly being overriten by something further down the line in the IIS pipeline.

Edit 1

Tried the following, no good either

public class SecureServerHeaderModule : IHttpModule
{
    #region Implementation of IHttpModule

    public void Init(HttpApplication context)
    {
        context.PreSendRequestHeaders += OnPreSendRequestHeaders;
    }

    public void Dispose() { }

    #endregion

    private static void OnPreSendRequestHeaders(object sender, EventArgs e)
    {
        var context = HttpContext.Current;
        if (context != null)
        {
            context.Response.Headers.Remove("Server");                
        }
    }
}

<system.web>
  <httpModules>
    <add "snip" />
  </httpModlules>
</system.web>
<system.webServer>
  <modules>
    <add "snip" />
  </modlules>
</system.webServer>

Edit 2

Also did not work.

public void BeforeSendReply(ref Message reply, object correlationState)
{
    var context = OperationContext.Current;
    if (context != null)
    {
        context.OutgoingMessageProperties.Remove(
            HttpResponseHeader.Server.ToString());
        context.OutgoingMessageProperties.Add(
            HttpResponseHeader.CacheControl.ToString(), "no-store");
    }
}

回答1:


This works using an IDispatchMessageInspector

public class SecureBehaviour : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref Message request,
        IClientChannel channel, InstanceContext instanceContext)
    {
        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {

        var httpCtx = HttpContext.Current;
        if (httpCtx != null)
        {
            httpCtx.Response.Headers.Remove(
                HttpResponseHeader.Server.ToString());
        }
    }
}



回答2:


Since you are hosting your service in IIS and have an HttpModule already spun up, try setting the ASP.NET Compatibility mode so that you can get to HttpContext.Current. You will need to make the following changes:

Modify your web.config and add the following to System.ServiceModel

<system.serviceModel>
  ...
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>

Decorate your service class with this attribute:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

Give the HttpModule another shot and you should have better luck.




回答3:


Have you tried editing your web.config and using the customHeaders tag under system.webServer.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <remove name="Server" />
        <remove name="X-Powered-By" />
        <remove name="X-AspNet-Version" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

This results in my C# ASP.NET application only having the following response headers:

HTTP/1.1 200 OK
Cache-Control: max-age=3600, public
Content-Length: 20992
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Last-Modified: Tue, 15 May 2012 18:01:11 GMT
ETag: "HHktEL5IWA6rspl4Bg2ZxNmnV3gTUCLt2cTldSsl05A="
Vary: Accept-Encoding
Date: Tue, 17 Jul 2012 21:38:38 GMT

Although I will admit I have not tried it with the "Server" header, this approach seems to work well. The reason I have not tried it with the "Server" header is that the following code in my IHttpModule works just fine.

    void PreSendRequestHeaders(object sender, EventArgs e)
    {
        HttpApplication application = (HttpApplication)sender;
        if(HttpRuntime.UsingIntegratedPipeline)
        {
            application.Response.Headers.Remove("Server");
            application.Response.Headers.Remove("Expires");
            application.Response.Headers.Remove("Cache-Control");
            application.Response.AddHeader("Cache-Control", "max-age=3600, public");
        }
    }



回答4:


Work in progress.

This blog entry answers a little more about the different pipelines and why ASP.NET modules aren't quite working.

More to follow.




回答5:


For my self-hosted WCF service the answer from M Afifi does not work. I have to set an empty header:

httpCtx.OutgoingResponse.Headers.Add(HttpResponseHeader.Server.ToString(), string.Empty);

This removes the header from the response:

access-control-allow-headers →Content-Type, Authorization, Accept
access-control-allow-methods →GET, POST
access-control-allow-origin →*
content-type →application/json; charset=utf-8
date →Mon, 03 Jul 2017 07:22:17 GMT
status →200



回答6:


Do you have access to the registry? If so you could try

HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\DisableServerHeader


来源:https://stackoverflow.com/questions/11455273/remove-server-from-http-response-in-wcf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!