2

I'm working on a small Restful API, which will show users current weather conditions in their location in the header of the page. There will be a GET query sent to the server via Ajax to a link similar to this:

https://test.com/weather/{required location}

Test.com represents my link which further queries either the database or external APIs. It responds with JSON and they will see the weather for their location. The problem that I have is if that link is accessed directly, it just prints the output, so potentially it could get farmed.

The question I have is how can I implement some sort of logic where if the the page is accessed via ajax from test.com, the output is JSON as needed. Any other ways to access that link will display a blank or custom page with JSON hidden?

Also, as I am new to API and Ajax work, are there any other security means I need to be aware of?

I'm using jQuery, php and mysql.

Thanks

Victor Nik
  • 77
  • 7

2 Answers2

0

I just found a partial solution myself, using Dontfeedthecode's idea of utilising $_Server varialbes. The one that is suitable is $_SERVER['HTTP_X_REQUESTED_WITH'].

if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
    echo 'JSON RESPONSE HERE';
} else {
    echo 'ALTERNATIVE PAGE HERE';
}

Found out that when Ajax query is sent with 'X-Requested-With: XMLHttpRequest' header according to this. So if we look for the header, we can find out how to treat it. However, from my understanding this will not prevent potential farming.

I will further investigate Dontfeedthecode's response to see if I can get it to work against farming.

Victor Nik
  • 77
  • 7
-1

You can check $_SERVER['HTTP_HOST'] against allowed domain names.

Taken from: PHP $_SERVER['HTTP_HOST'] vs. $_SERVER['SERVER_NAME'], am I understanding the man pages correctly?

$allowed_hosts = array('foo.example.com', 'bar.example.com');

if (!isset($_SERVER['HTTP_HOST']) || !in_array($_SERVER['HTTP_HOST'], $allowed_hosts)) {
    header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request');
    exit;
}

This may be a duplicate of: Prevent Direct Access To File Called By ajax Function

Community
  • 1
  • 1
Tim Sheehan
  • 3,712
  • 1
  • 11
  • 17
  • if I do this and access the link via browser directly, not via ajax, the above if statement returns false and still displays the json response... – Victor Nik Nov 22 '15 at 14:11
  • @VictorNik the only way your browser could still return the JSON is if you were outputting the response before conditionally terminating the script based on the HTTP_HOST. – Tim Sheehan Nov 22 '15 at 14:17
  • if I print_r($_SERVER['HTTP_HOST']) on a page that was loaded directly, not via ajax, I still get test.com, so setting a condition with will not stop the output. I think even if it was to be farmed, as long as the farming website send the query to my full link, they will still get json response since http_host will still equal test.com – Victor Nik Nov 22 '15 at 14:41
  • @VictorNik http://stackoverflow.com/questions/1756591/prevent-direct-access-to-file-called-by-ajax-function – Tim Sheehan Nov 22 '15 at 14:51