aspnet / Hosting

[Archived] Code for hosting and starting up an ASP.NET Core application. Project moved to https://github.com/aspnet/Extensions and https://github.com/aspnet/AspNetCore
Apache License 2.0
552 stars 312 forks source link

Add an "X-Powered-By" and "X-AspNet-Version" header #327

Closed DamianEdwards closed 5 years ago

DamianEdwards commented 9 years ago

From aspnet/KestrelHttpServer#138

benaadams commented 9 years ago

Following up from @Daniel15 comment

Is it worth adding something like X-Powered-By too? The server header is usually overwritten by reverse proxies (eg. Nginx).

Looks that that's a bug in the proxy? rfc2616 14.38 Server

If the response is being forwarded through a proxy, the proxy application MUST NOT modify the Server response-header. Instead, it SHOULD include a Via field (as described in section 14.45).

benaadams commented 9 years ago

Also:

Note: Revealing the specific software version of the server might allow the server machine to become more vulnerable to attacks against software that is known to contain security holes. Server implementors are encouraged to make this field a configurable option.

Daniel15 commented 9 years ago

Looks that that's a bug in the proxy?

The section you quoted is for "regular"/forward proxies. RFC2616 says:

The Server response-header field contains information about the software used by the origin server to handle the request.

With a reverse proxy, the proxy itself is considered the origin server. See http://trac.nginx.org/nginx/ticket/538.

In RFC2616 terms, a reverse proxy is closer to a "gateway" than a "proxy", which has no special conditions in section 14.38:

gateway: A server which acts as an intermediary for some other server. Unlike a proxy, a gateway receives requests as if it were the origin server for the requested resource; the requesting client may not be aware that it is communicating with a gateway.

benaadams commented 9 years ago

RFC2616 does give conditions for a gateway in 14.45 Via

The Via general-header field MUST be used by gateways and proxies to indicate the intermediate protocols and recipients between the user agent and the server on requests, and between the origin server and the client on responses.

The fact the nginx bug tracker they consider themselves to be the origin server and quote the "as if":

returns the content as if it was itself the origin

in apache mod_proxy to justify this is a bit of a reach since; it doesn't say overwrite server header and it then continues to say:

A typical usage of a reverse proxy is to provide Internet users access to a server that is behind a firewall. Reverse proxies can also be used to balance load among several back-end servers, or to provide caching for a slower back-end server. In addition, reverse proxies can be used simply to bring several servers into the same URL space.

The reverse-proxy acts as the origin for networking purposes meaning no client configuration is required.

Following nginx argument though; it would mean all load balancers should overwrite the server header and all caches should overwrite the server header; which doesn't happen.

Examples of other reverse-proxies:

Also mod_proxy which they quote to justify doesn't overwrite the server header when used as a reverse proxy and they explicitly state this: http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#ProxyPassReverse

This directive lets Apache httpd adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses. This is essential when Apache httpd is used as a reverse proxy (or gateway) to avoid by-passing the reverse proxy because of HTTP redirects on the backend servers which stay behind the reverse proxy.

Only the HTTP response headers specifically mentioned above will be rewritten. Apache httpd will not rewrite other response headers, nor will it by default rewrite URL references inside HTML pages.

Your comparison to gateway is accurate and nginx is poorly behaved.

Edit: Though I can't log a bug against nginx as their bug tracker auth is broken :unamused:

benaadams commented 9 years ago

Updated nginx ticket: https://trac.nginx.org/nginx/ticket/538#comment:4

darrelmiller commented 9 years ago

It is worth noting that RFC 7231 has removed the language about proxies not being allowed to modify the server. I have not yet found the specific reasons why it was removed. I suspect the use of the word proxy in the 2616 text was intended to mean "intermediary". I'll see if I can find some notes.

I personally don't think the intent of saying that a reverse-proxy looks like the origin web server to the client was intended to allow it to mask the existence of all infrastructure behind it. The whole point of the layered architecture and the uniform interface is that each layer looks like the origin server.

darrelmiller commented 9 years ago

RFC 7230 states:

An HTTP-to-HTTP gateway MUST send an appropriate Via header field in each inbound request message and MAY send a Via header field in forwarded response messages.

A "gateway" (a.k.a. "reverse proxy")

Based on this I would argue that it is valid for a gateway to add its identifier to the Via header of a response and therefore leave the server header untouched. It is also valid for the gateway to change the server header and not add a via header. This is a change from 2616 which said gateways MUST add a via, which in practice they were not doing.

The change is documented here http://trac.tools.ietf.org/wg/httpbis/trac/ticket/460 My suspicion is that people defended the "nginx is an origin server" to avoid violating the "it must include a VIA" header from 2616.

Personally I would like to avoid having the X-Powered-By and X-ASPNET-Version headers appear in my responses.

benaadams commented 9 years ago

Interesting; have updated the ngnix ticket

guardrex commented 9 years ago

Personally I would like to avoid having the X-Powered-By and X-ASPNET-Version headers appear in my responses.

:+1: Please provide control to deactivate if it this request is approved. I think we should have that for Server, too. Otherwise, you have to go to this trouble:

public void Configure(IApplicationBuilder app) {
    app.Use(next => 
    {
        return ctx => 
        {
            ctx.Response.Headers.Remove("Server");
            return next(ctx);
        };
    });
    app.UseMvc();
}
Eilon commented 9 years ago

Whatever we do for this definitely must be turn-off-able. In previous versions of ASP.NET there was always a switch for this.