Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only accept AJAX $_GET or $_POST requests from specific page

Tags:

ajax

php

Is it possible to check that the $_GET or $_POST values are submitted from specific page?

For example, there is an ajax in page1 submitted value to page2.php?q=abc, and the page2 only accept the q when it is submitted from page1.

If I directly browse to the page page2.php?q=abc, the php will not run unless I submitted the value from page1.

Is it possible to do that?

Edit 1:

Because I can access the page2 and get the result. Don't mention about the session, because I can validate the session to match my needs and the values submitted to php is valid or not.

What I want is to check if the request is sent from specific page or not. If true, then accept the values and process it, else, redirect to homepage or something else.

Edit 2: My question is, not only values submitted through Ajax, but also direct access, such as href="page2.php?q=abc". I guess token will be the best way to do that, and the query part will validate again.

like image 457
Chin Avatar asked Feb 14 '23 01:02

Chin


2 Answers

There are two security checks you could perform while dealing with AJAX:

1) Check if the request it sent through AJAX:

if ( !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' )
{
       //AJAX Request Detected
}

2) Hashed tokens:

On the page that's holding the AJAX Request, create a token:

session_start();
$hashed='';
$_SESSION['token'] = microtime(); 
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
    $salt = '$2y$11$' . substr(md5(uniqid(mt_rand(), true)), 0, 22);
    $hashed = crypt($_SESSION['token'], $salt);
}

This is using the blowfish algorithm with the crypt() to create hashed string.

Your AJAX function would be like:

$.ajax({
    type: "POST",
    url: 'page2.php',
    data: {
        action: '<?php echo $hashed;?>', //pasted the hashed string created in PHP
        q: 'test'
    },
    success: function (data) {}
});

Upto you whether you want to use $_GET or $_POST method.

And then on the second page which is receiving the AJAX request, you do:

session_start();
if(crypt($_SESSION['token'], $_POST['action']) == $_POST['action']){
   //Hashed string matches. Request has come from page1.
   echo $_POST['q'];
}
like image 110
AyB Avatar answered Feb 23 '23 07:02

AyB


in your form you can just add a hidden field and add a page id. On the page that should send post or get request you can do something like

<form action='phpscript.php'>
    <input type='hidden' name='page' value='valid_page'>
    <input name='your_other_info'>
</form>

In the phpscript.php you can do something like

<?php
    //If you have a request, it can be either post or get method
    if(isset($_SERVER['REQUEST_METHOD']) && (isset($_POST['page']) || isset($_GET['page']))){

    }else{
        //Post or get is not from the valid page
    }
?>
like image 27
ksealey Avatar answered Feb 23 '23 08:02

ksealey