2

I have a lot of php files updating my database, but I want these to only work when called in my code (usually by ajax).

Now, if I put the URL of the php file, it updates the database, and if I put ajax code in inspect element, the database updates.

I don't want people messing around with information that is not supposed be changed by them.

How do I fix this?

Ex.

In one of the files I add 1 to a db value. If I put the link to this file in the browser, it adds one. If I put ajax to go to this link, it also updates the DB. This is really bad for security on the site.


Edit: i'm trying to implement the top rated answer but I'm getting the error:

Unexpected token '.'. Expected a ':' following the property name 'myreq'.

Here is my code:

var myreq = new XMLHttpRequest();

$.ajax({
    headers: {
        myreq.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    }
    url: 'http://myurl.php',
    data: {},
    type: 'post',
    success: function(output) {
    }
});

I might have to put the myreq part under beforeSend instead of headers but idk, I'm new to this.

Sloan Thrasher
  • 4,953
  • 3
  • 22
  • 40
Patrick
  • 111
  • 12
  • 3
    _"either by ajax or another way"_ - What is _"another way"_? Also, if you want your PHP scripts to be accessible from the front end (like ajax), there isn't really a way to 100% stop people from accessing them directly. You could check if the call is through Ajax, but that can be spoofed. You can also implement some CSRF-protection that makes it harder as well. Also, you shouldn't allow GET-requests to update data. You should either use POST or PUT which would at least stop direct access through the browser. – M. Eriksson Aug 23 '18 at 21:09
  • You could use a session variable to identify calls as coming from your web page. However, even that can be called by an experienced hacker. It would prevent the average user from being able to call it. – Sloan Thrasher Aug 23 '18 at 21:09

4 Answers4

3

If you want to prevent direct access to your php file and allow only AJAX calls , As described in Prevent Direct Access To File Called By ajax Function Question :

You can use this code on your server side :

if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
    // allow access....
} else {
    // ignore....
} 

And add header to ajax requests for client side:

var myreq = new XMLHttpRequest();
myreq.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 

With this solution you prevent abuse from opening that file in a standard browser

But keep on mind : Everything on client side can be spoofed. So if you want to prevent abuse you need to change the way you update your database value. Or at least add IP check or session check or captcha to make it harder for hacker to abuse...

In this example , a hacker can spoof ajax calls

PHP 7 UPDATE :

Thanks to Stephen R (For commenting) AS OF PHP 7 You can replace the If statement with following code to have a cleaner code:

if( ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? 0 ) === 'XMLHttpRequest' )
M4HdYaR
  • 1,124
  • 11
  • 27
  • Ill try it out, thank you. If i do this though, hackers can only get through using a method that can't get through captcha? So if i implement both this method and IP Check or Captcha, a hacker won't be able to get through? – Patrick Aug 23 '18 at 23:05
  • @Patrick you only make it harder for a hacker to do it , so hard but not impossible. The best way is change your way you update your database , for example a way of authenticating. Or something like that... – M4HdYaR Aug 24 '18 at 07:55
  • 1
    A bit cleaner `if()` for PHP 7: `if( ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? 0 ) == 'XMLHttpRequest' ) {`... – Stephen R Jul 11 '19 at 22:04
  • CORRECTION: `'XMLHttpRequest' == 0` evaluates to True. Use empty string `''` instead: `if( ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' ) == 'XMLHttpRequest' )`. Sorry 'bout that! – Stephen R Aug 08 '19 at 18:40
  • Or you can do a strict comparison: `=== 'XMLHttpRequest'`. See here for why this happens: https://stackoverflow.com/questions/6843030/why-does-php-consider-0-to-be-equal-to-a-string – Stephen R Aug 08 '19 at 18:41
  • @StephenR Thank you for your attention I didn’t pay attention to it. Just edited it, thanks. – M4HdYaR Aug 08 '19 at 19:01
2

For the code in your edit, there were several issues. You don't need the XMLHttpRequest. jQuery will add the headers, if you supply them as an array.

Also, you need a comma after the headers element. Note that the argument to the ajax function is an array and headers is just one of the elements in that array.

Try the following:

$.ajax({
    headers: {
        "X-Requested-With" : "XMLHttpRequest",
    },
    url: 'http://myurl.php',
    data: {},
    type: 'post',
    success: function(output) {
    }
});
Sloan Thrasher
  • 4,953
  • 3
  • 22
  • 40
  • 1
    Yes it worked, thank you! I'm going to upvote your answer but i'm going to have to label the other one as correct. Thanks again! – Patrick Aug 24 '18 at 01:07
0

You need to add in .htaccess file.

<Files ~ "^.*">
  Deny from all
</Files>

<Files ~ "^index\.php|css|js|.*\.png|.*\.jpg|.*\.gif">
  Allow from all
</Files>

Here its allowing only index.php and all css/js/images allow from browser direct url or ajax or calling from code.

Naveed Ramzan
  • 3,565
  • 3
  • 25
  • 30
0

If you're worried about security, you should require some kind of account registration so you can send some authentication data (preferably a token) with the request. Any kind of client side authentication (the only reason I can think of to require calls to originate from your site) is a terrible idea