How to protect the controller from WebAPI for use only by the local machine

I have an ASP.NET MVC website that uses WebAPI, SignalR.

I want my server (the same server that hosts the website) to make HTTP requests to the WebAPI controller - I want to do this so that I can connect to the SignalR functions on my site.

I want to make website users unable to access methods on the WebAPI controller, but the server can.

I looked at the options for securing WebAPI requests in general, and it seems to me that I have the following options:

  • Send username and password for each request. AKA Basic Authentication
  • Create a "Client Certificate" and send it with each request.

These are the only two methods that sound like they will work, but I wonder if these methods will overdo it if the requests come from localhost (the same server).

Is it really too complicated, is there an easier way to restrict HTTP requests from the local machine to a WebAPI controller?

+7
security c # certificate asp.net-web-api
source share
2 answers

If you ONLY wanted to accept requests created from the same computer, you can check the IsLocal property of the MSDN request context.

 HttpRequest.Context.Request.IsLocal 

You can then create it in a custom authorize attribute and register it globally, observing the requirement on all of your web API controllers.

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Other Web API configuration code goes here // This is a globally registered attribute config.Filters.Add(new LocalRequestOnlyAttribute()); } } public class LocalRequestOnlyAttribute : AuthorizeAttribute { protected override bool IsAuthorized(HttpActionContext context) { return context.RequestContext.IsLocal; } } 
+11
source share

I wanted to clarify whether HttpRequest.Context.Request.IsLocal safe or not.

I just decomposed IsLocal() from the HttpWorkerRequest and found the following code:

 internal bool IsLocal() { string remoteAddress = this.GetRemoteAddress(); if (string.IsNullOrEmpty(remoteAddress)) { return false; } if (remoteAddress == "127.0.0.1" || remoteAddress == "::1") { return true; } if (remoteAddress == this.GetLocalAddress()) { return true; } return false; } 

The first two checks look fine, but I was suspicious and wanted to check what this.GetLocalAddress() returns for checking.

In the case of System.Web.Hosting.IIS7WorkerRequest this decompiles the following:

 public override string GetLocalAddress() { return this.GetServerVariable("LOCAL_ADDR"); } 

In my local environment, this returns 127.0.0.1, so everything looks good!

Also, according to this post , localhost cannot be tampered with.

+1
source share

All Articles