0

I am working on building an API that will allow my applications to access necessary data from a MSSQL backend. Both the API application (an ASP.NET MVC Web API) and the caller (a PHP based application) will be running on the same server. Based upon an answer to another StackOverflow question, I implemented the following LocalFilter:

// REFERENCE https://stackoverflow.com/questions/14858787/lock-down-asp-net-mvc-app-administration-site-to-localhost-only/24283809#24283809
public class LocalFilter : AuthorizeAttribute
{
    public bool ThrowSecurityException { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var isLocal = httpContext.Request.IsLocal;
        if (!isLocal && ThrowSecurityException)
            throw new SecurityException();
        return isLocal;
    }
}

I decorated numerous controllers with it.

`

   [LocalFilter]
    [RoutePrefix("Hotels")]
    public class HotelsController : ApiController
    {
        UnitOfWork worker = new UnitOfWork();

        [Route("")]
        public string Get()
        {
            List<HotelDTO> dtoList = Mapper.Map<List<Property>, List<HotelDTO>>(worker.PropertiesRepo.Get(e => e.PropertyTypeID == 3).ToList());
            foreach(HotelDTO dto in dtoList) {
                dto.SliderImages = Mapper.Map<List<Image>, List<ImageDTO>>(worker.ImageRepo.Get(e => e.PropID == dto.ID && e.CategoryID == 2).ToList());
                dto.GalleryImages = Mapper.Map<List<Image>, List<ImageDTO>>(worker.ImageRepo.Get(e => e.PropID == dto.ID && e.CategoryID == 1).ToList());
            }

            return JsonConvert.SerializeObject(dtoList);
        }  /// MORE CODE FOLLOWS

`While this filter works as expected when I attempt to access an endpoint from my browser (I get an error), I am able to access it through a PHP script on my development machine.

    class APIWorker {

 const BASE_PATH = "http://www.mywebsite.com";
 // const BASE_PATH = "http://localhost:57263/";
    const AUTH_PATH =  "token";

public function getToken()  {

$body = Unirest\Request\Body::form($this->credentials);
$response = Unirest\Request::post(self::BASE_PATH . self::AUTH_PATH, array("Accept" => "application/json"), $body );
$this->token = $response->body->access_token;
} 


function getJSON(String $endPoint) {
    if(session_status() !== PHP_SESSION_ACTIVE) { session_start (); }

$url = self::BASE_PATH . $endPoint;

$credentials = $_SESSION["auth"] ?? ""; 

if($credentials != "") {
    $headers = array("Authorization" => "Bearer " . $credentials);
} else {
    $headers = array();
}

$response = Unirest\Request::get($url, $headers);

return json_decode($response->body);
}

To my (limited) understanding, this should not be the case. The PHP script is not (during testing) presently on the same server/machine as the ASP.NET MVC Web API. Why is Request.IsLocal returning true and how can I fix it so that remote scripts cannot access the data?

Thanks.

KellyM
  • 2,472
  • 6
  • 46
  • 90
  • 1
    https://msdn.microsoft.com/en-us/library/system.web.httprequest.islocal(v=vs.110).aspx By the doc's, it should only return true if the request is from 127.0.0.1 or the same ip address as the server. But I've seen this question on here before in other forms. – Greg Oct 26 '17 at 14:27
  • 1
    Others particularly don't like that it isn't just localhost, and thus consider other solutions. https://stackoverflow.com/questions/19010217/is-request-islocal-secure-or-can-it-be-spoofed https://stackoverflow.com/questions/12904417/request-islocal-alternative https://stackoverflow.com/questions/11879500/how-to-limit-page-access-only-to-localhost/11885883#11885883 – Greg Oct 26 '17 at 14:30

0 Answers0