0

I'm breaking my head over this issue, where I want to prevent people from direct accessing a file which I'm calling using AJAX.

In short:

  • main-script.php makes an AJAX call to ajax-request.php
  • ajax-request.php can only be called from from main_script.php
  • Prevent direct access to ajax-request.php

I've already read similiar questions like this one, but the "accepted answer" here (like many other of the answers) seems like it shouldn't be accepted. What got my attention however was this answer, where he's talking about using $_SESSION and hashing. Now the problem is (1) that I'm skeptical if you can actually prevent people from direct accessing in this case; (2) I can't wrap my head around on how you'd use sessions and hashing to make this happen.

So I would appreciate it if someone could help me out with the thinking process or give me a push in the right direction (or give advice if it's not really possible at all).

YTZ
  • 464
  • 4
  • 14
  • Why is it that you cannot allow direct accessing? – Toastrackenigma Jul 29 '19 at 01:11
  • 2
    You can't do that. All you can do it make it harder. – SLaks Jul 29 '19 at 01:15
  • @Toastrackenigma well I just don't want it to make it too easy to scrape data. I've already thought about rate limiting, but that's more of a workaround than an actual solution. – YTZ Jul 29 '19 at 01:22
  • 1
    It's absolutely possible. But with a lot of effort just to prevent direct access to a file that is essentially being accessed directly from a public request. In the simplest form you could just check if it's not accessed by an ajax request (simply loading the URL in the browser will return whatever error you bestow), alternatively, provide a tokenised form of communication between the two files. Either way, it can be done but not so much for me to explain in depth. – Cue Jul 29 '19 at 01:22
  • `X-Requested-With` (or setting another, custom header), and making sure requests are authenticated with a username and password or a valid session is probably the closest you are going to get. – Tim Groeneveld Jul 29 '19 at 01:53
  • *"well I just don't want it to make it too easy to scrape data"* I work these days on public proxies and scraping them from public proxies websites, and one of the hardest challenges that my scraper found is spys.one website. He encodes the ports number before sending them to the client which needs a javascript parser like normal a browser or headless browsers to decode these ports number to get useful information, check his method and try to apply custom solution like this to prevent **most** of the scrapers. – Accountant م Jul 29 '19 at 02:36
  • Can't you use an encrypted session ID to verify the request? – Fr0zenFyr Jul 29 '19 at 13:07

1 Answers1

-1

You can't prevent me from requesting yourdomain/ajax-request.php as long as I know there is some resource on that location, however you can prevent unauthorized access to this file, similar to the way to prevent guests from members areas on your website, or any resource that requires authorization. The deference is that I don't get an authorized access by providing a password , no I get that access to ajax-request.php only if I requested main_script.php

The simplest way I would do to accomplish this is with ($_COOKIE and database) or ($_SESSION), for example

main_script.php

$_SESSION['canRequestAjax'] = 1;

other_scripts.php

unset($_SESSION['canRequestAjax']);
/* 
 remove the variable if he visited something else, 
 because he can only request the ajax-request.php RIGHT AFTER the main_script.php
*/

ajax-request.php

if (empty($_SESSION['canRequestAjax'])){
    die('error'); // TODO: proper 403 response
}
unset($_SESSION['canRequestAjax']);
/* 
 remove the variable if he requested the ajax ajax-request.php file, only 1 ajax is allowed. 
NOTE: remove this line if the user may do more than 1 ajax requests when he is on
 main-script.php
*/
Accountant م
  • 4,969
  • 2
  • 30
  • 49
  • Problem with this is that by unsetting the cookie, the other php scripts will need to set the cookie again and that only happens at runtime. So any subsequent ajax requests will fail. This is a half-hearted effort. – Cue Jul 29 '19 at 02:08
  • @Cue this is intended, the OP needs to allow access to `ajax-request.php` **only** if the user is on `main_script.php`, for example : the user requested `main_script.php` then navigated to something else, he can't make ajax requests, I think this is what the OP wants. – Accountant م Jul 29 '19 at 02:17
  • One of the OP comments were "I've already thought about rate limiting, but that's more of a workaround than an actual solution". This solution is somewhat rate limiting. – Cue Jul 29 '19 at 02:19
  • @Cue hmmm, so the OP needs to prevent bots from requesting this resource! that is a different story, I answered the question of **how to make `ajax-request.php` accessible only from `main_script.php` ?** and BTW this solution has nothing to do with rate limiting, the scrapper will be programmed to request 1- `main_script.php` 2- `ajax-request.php` instead of 1- `ajax-request.php` directly, without any limits, he should search for preventing bots and this area – Accountant م Jul 29 '19 at 02:31
  • The problem here is if I access `main-script.php` once and save the cookie, I can just supply the cookie with the request too `ajax-request.php`, making it still too easy. And it's not really a matter of bots (never said that), more like "everyone should be blocked direct access and it should only work when the request is an AJAX call from `main-script.php`". So your solution will only work too some extent , assuming a guest didn't access `main_script.php` before that. – YTZ Jul 29 '19 at 12:17
  • @YTZ *"if I access main-script.php once and save the cookie"* .... This model allows you to make only 1 ajax call if you requested `main-script.php` and to make another ajax call you have to request `main-script.php` another time, it's not like visit `main-script.php` once and get access to ajax file forever, isn't this what to wanted ?. I used sessions BTW because a scraper can include the cookie easily in his request to `ajax-script.php` without accessing `main-script.php` first. – Accountant م Jul 29 '19 at 13:01