开发者

Is there any way to prevent AJAX pages from being viewed alone in a browser?

开发者 https://www.devze.com 2023-01-13 13:54 出处:网络
For example, when I want to update a part of my page with AJAX I would normally make the appropriate call to getPost.php which would return the markup to be inserted into my page. Is there any way to

For example, when I want to update a part of my page with AJAX I would normally make the appropriate call to getPost.php which would return the markup to be inserted into my page. Is there any way to prevent开发者_如何学Go a user from accessing this page directly (eg: example.com/getPost.php with the appropriate GET or POST arguments) and getting only part of the page since this should be used with AJAX as part of a whole, not alone?

I don't think permissions can be set on the file since it's the client requesting the page but is there a way to do this by passing an extra argument that can serve as a check digit of sorts.


You could take a look at the request headers and enforce that a header must be set for AJAX requests (often people use X-Requested-With with a value like XMLHttpRequest). Be aware that this header won't be set unless you set it yourself when you make your AJAX request (or use a Javascript library that does it automatically). However, there is no way to guarantee that someone wouldn't add in that header on their own if they wanted to.

The X-Requested-With header value can be found in $_SERVER['HTTP_X_REQUESTED_WITH'].


You can check the $_SERVER['HTTP_X_REQUESTED_WITH'] header. It should be equal to the value 'XMLHttpRequest' if it is an Ajax request.

Edit - like Daniel Vandersluis said, there is no way to fully enforce this. You can spoof user agent, referrer - anything that comes in with the request.


what ever you request to server, it store the information in $_SERVER variable

to check what information this variable stores try this

print_r($_SERVER);

//you will see the difference in http and ajax request 

use this variable to check as bellow

if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
    strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
   //ajajx request
}
else {
   //not an ajajx request
}


Since there's no way to be 100% sure who is asking the question, you can restrict the question itself.

The implementation of this will depend on the page of course.

For example let's say you're running curl command on a url, you can restrict the incoming variable to only a certain domain.

<?php
if (substr($_GET["url"], 0, 19) !== "http://example.com/")
{
    die();
}
// otherwise carry on
?>


shouldn't this work?

if(preg_match("/getPost\.php/", $_SERVER['PHP_SELF'])){
     // Access to file directly, quit..
     die();
}


I think you can (at least partially) solve your problem with cryptography.

Say you have a page main.php which includes JS to call another page called ajax.php. When the page main.php is accessed, use a $browserKey and a $salt to create a $_SESSION["tempHash"]. (You also need to store the salt.) Then, give the key to the JavaScript making the request to your page ajax.php, and check that the key and salt give the same hash as before. On main.php, do something like this:

<?php
session_start();
// authorize user here
$salt = time();
$browserKey = mt_rand();
$hash = sha1("$browserKey$salt");
$_SESSION["tempSalt"] = $salt;
$_SESSION["tempHash"] = $hash;
// ... code ...
?>
<!doctypehtml>
<html>
<!-- html -->
<script>
// ... ajax call ...
var params = "param1=val1&param2=val2&...&browserKey=<?= $browserKey ?>";
request.send(params);
</script>
</html>
<?php session_write_close(); ?>

Then, on ajax.php, simply do

<?php
$validated = false;
if(sha1($_POST["browserKey"] . $_SESSION["tempSalt"]) === $_SESSION["tempHash"]) {
    $validated = true;
}
// and unset the salt and hash
$_SESSION["tempSalt"] = $_SESSION["tempHash"] = null;
if(!$validated) {
    // taken from another SO answer: 
    // http://stackoverflow.com/a/437294/2407870
    header('HTTP/1.0 404 Not Found');
    echo "<h1>404 Not Found</h1>";
    echo "The page that you have requested could not be found.";
    exit();
}
// else, continue normal processing here
?>

I'm not an expert in this domain, so take my advice with a grain of salt. (Heh, cryptography joke.)

One potential vulnerability with this approach is that the person may load page main.php and then wait five hours and call page ajax.php. It will still only allow them to access it once though. And you can do other things to prevent this. E.g, check the salt (which was obtained with time()) to verify that not too much time has passed. Or even send periodic heartbeats to the server, which generate a new hash, salt and key, returning the new key to the browser.

0

精彩评论

暂无评论...
验证码 换一张
取 消