PHP disable execution from browser - php

My site is like this that user opens it and runs index.php, and in index.php there are many ajax calls to other php scripts in same server directory as index.php. Now im using post, but if user comes to know addresses of these other scripts (like from right-click ---> view page source) then he can run those scripts in their browser, which can lead to inconvenience (e.g sometimes causing blank entries to be inserted in to database, just an example). So how do I disable php execution of those scripts from a browser yet ajax can call them?

You can't, at least not reliably (you can use JavaScript to add extra request headers, for example, but the user can observe those requests and add the headers themselves).
Check that submitted data is sane instead. If a submission to add a blank entry comes, throw an error message back.

you should check in php script if it is Ajax Reponse
/* AJAX check */
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
echo 'call from ajax'; //here you have call request by ajax
}
else
{
die("You shouldn't be here");
}
/* not ajax, do more.... *
Source of code
Most of well known JS libraries use this header. If you don't use library you can set this header by your own.
var req = new XMLHttpRequest();
req.setRequestHeader("HTTP_X_REQUESTED_WITH", "xmlhttprequest");
These headers can be set when attacker tampers data but for common guy who wants to access page via browser it will show "you shouldn't be here" message.

Here's what I use to detect AJAX requests:
function isAjax()
{
/* AJAX check */
return (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
}
Please note that this does NOT guarantee detection and can only help stall misguided users, not determined attackers.

Related

Handling users that visit a PHP process page without POST

This question addresses the security / user end side of things.
Suppose I have a script that is called via ajax which will add something to a database.
The script checks for the request method. If it is from 'POST' then the script will carry out this function.
I do not want users accessing my pages and either getting an error or a blank page.
What is the 'ideal' way to deal with this?
My current plan is as follows: If it is not a POST method, redirect them to an error page in the same way as a 404 handler and then provide some links for elsewhere.
Returning a 400 Bad Request is a pretty standard way to indicate that the user got there without the proper data that's needed.
if(!isset($_POST)){
header("HTTP/1.0 400 Bad Request");
}
On top of that, you should spend some time investigating doing some cross site request forgery protection (CSRF) if you want to make sure only your UI posts to that page.
Try this, i use it in all my pages called via ajax:
if ($_POST['ajax'] == "ajax") { // You need to set this is your post ajax variables sent to this php file.
// all your code here
} else {
// Not needed for a blank page, or whatever you want for another page ie
header ("location: 404.php");
}

Allow access to PHP file only through ajax on local server

I have a website that needs to increment values in a database based upon user interaction. When users click a button a php script is called that increments the value. I'd like to protect this script from being accessed by outside scripts. Currently a user could write their own web page with a javascript function that hits the same php file repeatedly to blow up the value in the database.
Here's my jquery code that does the incrementing:
jQuery(function(){
$('.votebtn').click(function(e){
var mynum = $(this).attr('id').substring(0,5);
$.ajax({
url:"countvote.php",
type:"GET",
data: {
thenum:mynum
},
cache: false,
success:function(data) {
alert('Success!');
}
}
});
});
});
How would I go about making it so that only a call from ajax/jquery on the local server can access 'countvote.php'? If that's not the correct way to go about it, I'm open to any suggestion that will prevent my php script from being abused by outside scripts.
The solution needs two steps.
Firstly the ajax file must allow access only in ajax request with this code.
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(!IS_AJAX) {die('Restricted access');}
Secondly the ajax file has access in the name of file that call it with command $_SERVER['HTTP_REFERER'].
So you can restrict access only in the host server.
$pos = strpos($_SERVER['HTTP_REFERER'],getenv('HTTP_HOST'));
if($pos===false)
die('Restricted access');
Maybe the code can work only with the second part
You can check if $_SERVER['HTTP_X_REQUESTED_WITH'] equals xmlhttprequest, but it's not a reliable method to determine whether a request is an AJAX request or not, there is always a way to get around this. But it protects you from random hits like wrongly entered urls, crawlers etc.
Theres not really a 100% method of doing so. AJAX requests are always going to come from a client. Use POST requests instead of GET and that will help deter any issues but not completely stop them and in your php, just drop all get requests.
I am not sure if this will work, but whats about settings an API key on eg. index.php into a $_SESSION variable, afaik this cannot be visible to the user, unless you do it manually, then in the restricted php file, check the $_SESSION['VOTEAPIKEY'] or whatever

PHP/js session expiration loads whole page in dv

I have a password protected website--imagine something like linkedin-- where if the session expires you are prompted to log in again.
Some pages have ajax calls, however, that load content from the server into divs.
If you come back to the open div after the session expires and try to enter something, the php on the other end does a redirect within the div, and basically loads the whole login page inside the div. This creates a page within a page, an obvious error that tells the user, the site is not working properly.
Instead of the login page appearing inside the open div, I would like the div to close and the whole page redirect to the login. I am having trouble accomplishing this, however.
Right now I am doing the password protection with an include that checks for session and either allows you to continue or bumps you out to the login page.
If ($_SESSION['login'] != '1') {
header("Location: relogin.php"); }
I have this include in the scripts triggered by ajax calls to fill divs so users cannot bypass security. It is a catchall include that also holds some global variables, functions and so forth.
Can I add code that detects if call is coming from ajax or something so as not to do redirect and instead give message to login. Or ideally, close div and redirect whole page?
Because it is a large site, I would like to find one block of code that could go into the global include.
Would appreciate any suggestions.
You will need to do the redirect on the JS side.
Let's go over the PHP side first. You want to give your AJAX handlers a clear, unambiguous, stateful response: "sorry, you're not authorized". Let's borrow from REST a bit right?
Top of each of your AJAX calls:
<?php if (!YouAreLoggedIn()) {
header($_SERVER['SERVER_PROTOCOL']." 403 Forbidden");
exit(); ?>
This will throw the visitor a 403 error, and will kill the script. 403 errors in jQuery count as a XHR error, so you can map it independently of everything else.
Your typical AJAX call then becomes:
$.ajax({
url: "your.url.here.php",
type: "POST",
success: function(d) { YourSuccessCallHere(); },
error: function() { window.location.href='your.redirect.here.php'; }
});
This is the cleanest way to do it.
You could differentiate the two different calls by User-Agent or other header fields.
Use setRequestHeader() as described in links below:
JQuery Ajax Request: Change User-Agent
http://www.w3.org/TR/2007/WD-XMLHttpRequest-20070618/#dfn-setrequestheader
You could add a GET variable to the request URL whenever you're calling it via Ajax:
myurl.php?ajax=Y
Then on myurl.php, check to see if it's an ajax call:
if(!isset($_SESSION['login']) || $_SESSION['login'] != '1') {
if(isset($_GET['ajax'])){
echo json_encode("Please login!");
exit;
}
else{
header("Location: relogin.php");
exit;
}
}
Use the following header to check if the request was an AJAX request:
X-Requested-With: XMLHttpRequest
read the header in php using:
$_SERVER['HTTP_X_REQUESTED_WITH'];

ajax- if I send an ajax request on a url, can i check in the php page if it is a request or the page has been opened?

For security purposes, I want to stop the users from being able to view or send anything to the php pages I am going to use for ajax purposes.
So is there any way by which I can check whether a page has been called because of an ajax request or the page has been opened?
Does self=top consider ajax request or not?
/* AJAX check */
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
/* special for ajax here */
}
else
{
//its a page request
}
this will only work when using JS frameworks that send this header :-by Bergi
No, you will need an other security model.
Of course you could set custom http headers (like X-Requested-With) or such when you are doing Ajax requests (many libraries do that automatically), and tell them apart from normal "view" requests. But everything can be faked, so there can be no security through determining that.
Even if you do stop people not using a ajax request, what's stopping people from changing the ajax request in the first place?
This would add little to none added security in my opinion especially with the ease this can be done with firebug for example.

encrypting jquery .load() function

I'm calling a php page using .load()
.load('page.php?user='+user+'&page='+page)
if you go to the actual page.php and type page.php?user=1&page=2
you get the same result, how could I stop this from happening?
encrypting data maybe?
Could someone point me in the right direction, cheers.
#lonesomeday,
this answer works for me, yours was correct though:
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { it's an ajax request validate id and continue! } else { this is not an ajax request, get out of here! }
submitted by "ifaour"
Ultimately, anything that is accessible using AJAX is accessible without using AJAX. That's the nature of the web.
You can try to ensure AJAX by checking for the XMLHTTPRequest header, but be aware that it can trivially be spoofed by a user who wants to:
if ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHTTPRequest') {
// is probably an AJAX request
}
If you are making your request with jQuery, this should be safe, because jQuery adds this header itself. Be aware, though, that some browsers do not add it automatically if you are creating the XMLHTTPRequest object yourself.

Categories