I have a Web Application that can be installed in multiple environments, including on servers where it might be exposed via a CloudFlared tunnel.
When a user accesses the Web Application via the CloudFlared tunnel, Request.IsLocal returns True even though the user is not local.
I created the following class which uses the request.Headers to help detect the use of a local tunnel and therefore lets me get a corrected IsLocal value.
My question is, "Is this solution sufficient, or am I exposing a security hole that I don't see..."
internal class RequestSecurity
{
const string PROXY_CLOUDFLARE = "cloudflare";
const string PROXY_UNKNOWN = "proxy";
const string INTERNAL_LOCALHOST_IP = "::1";
private HttpRequest _request;
public string BaseIP { get => _request.UserHostAddress; }
public string ForwardedIP { get; internal set; }
public string ProxyType { get; internal set; }
public bool IsLocal { get => _request.IsLocal && ProxyType is null; }
public bool IsCloudFlared { get => ProxyType == PROXY_CLOUDFLARE && BaseIP == INTERNAL_LOCALHOST_IP; }
}
public RequestSecurity(HttpRequest request)
{
_request = request;
// Check for Proxies.
var fromCloudFlare = request.Headers["cf-connecting-ip"];
var fromMiscProxy = request.Headers["x-forwarded-for"];
ProxyType =
!String.IsNullOrEmpty(fromCloudFlare) ? PROXY_CLOUDFLARE
: !String.IsNullOrEmpty(fromMiscProxy) ? PROXY_UNKNOWN
: null;
// Cloudflare is the outermost proxy, most likely closest to the client.
ForwardedIP = fromCloudFlare ?? fromMiscProxy;
}
}
To use the class simply call as follows...
if ((new RequestSecurity(Request)).IsLocal)
.. do local stuff ..
var requestSecurity = new RequestSecurity(_request);
if (requestSecurity.IsLocal)
.. do local stuff ..