简体   繁体   中英

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

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.

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'];
}

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
    }
?>

You cannot restrict the "origin" of the request, because there's no such thing per se. Your "page" isn't sending a request, it's the browser that does it. And the browser may have any number of reasons why it's sending you a request; be that because one of your pages has instructed it to do so or because a user is fiddling around with the Javascript console manually.

All you get on your end is an HTTP request. Go ahead, inspect it. In the browser, look at the network tab and inspect the raw request being sent. It's just a bunch of HTTP headers, nothing more. Anyone can send an HTTP request with arbitrary HTTP headers any time from anywhere and make it look like anything they want. Even the Referer HTTP header is not going to "protect" you.

If you need any sort of protection, you can use session tokens or user authentication to restrict the set of potential entities that can send queries somewhat. But what you have is still by definition a public URL endpoint which answers to arbitrary HTTP queries. You cannot restrict their "origin page". The best you can do is obfuscate it by requiring certain headers to be set (like Referer or X-Requested-With).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM