Prevent user to see directly PHP url in Javascript - php

I want to prevent user to see directly PHP URL in Javascript.
Example :
{
$.ajax(
{
type: "POST",
url: "search.php",
data: dataString,
cache: false,
success: function(html)
{
$("#display").html(html).show();
}
});
}return false;
Is it possible or any way to prevent user see the php URL when He/She view the source of my page ? Sometimes user maybe try to open the php url directly.
Thanks for helps.

I (or any client) can still use any number of tools to figure it out (including the built-in debugger in 99% of the browsers built)--It's not worth obfuscating it.
If you're concerned about direct access, check for an AJAX request in your script. (Still hack-able, but it's a start). As also provided in a previous answer:
<?php
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
if (!$isAjax) die('Unauthorized access');
/* rest of search.php */

As stated in comments,
How can We prevent the User open directly the PHP url ?
You should create a session of very long random string (token) in your php and pass it to the js ajax function, so that it sends the token along with the ajax request. On server side you can check if its the same token generated. You may want to expire the token soon.
I dont know, if its the standard way, but can provide you a start.

Ok to make things clear..
Once its on the client-side(the browser) you can't hide it. Users can still download or view source the client-side return.
Obfuscating is not really needed because you just make things complicated and not protecting anything.
But anything that is server-side code(PHP) will not be shown as it is processed by the server-side and the server just return the results of execution of the server-side code.
well in case of your problem the thing you can do is to check whether the $_POST and $_GET parameters are valid upon reaching your PHP codes thus making every POST and GET request valid and safe. its somewhat like this
<?php
if(isset($_POST['username']) && isset($_POST['password'])){
//everything seems fine
echo 'ok';
}
else{
//someone is doing a direct acess
header('index.php');
}
?>
or check the sessions to protect your pages only for logged-in users
<?php
if(isset($_SESSION['userid'])){
//everything seems fine
echo 'ok';
}
else{
//someone is doing a direct acess
header('index.php');
}
?>

Related

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

Prevent external acces to .php

Is there a way to block external acces to a .php file (like in the URL) and allow if the .php file got called by jquery post?
Thanks!
Wouter0100
I assume because you say like in the URL you want to prevent GET requests.
You can put this at the top of your script to prevent people accessing it through the URL. You will then only be able to POST to it, such as jQuery POST.
<?PHP
if($_SERVER['REQUEST_METHOD']!="POST")
header('HTTP/1.0 401 Unauthorized');
exit;
?>
Be aware, other sources can still POST to the form as well. This method only prevents access through other methods such as GET requests. I.e. typing in the URL in the address bar.
As it has been mentioned to you that allowing a .php to be accessed using jquery post is equivalent of providing an external access. The only way (and that is not very reliable) you can allow a php file to be accessed by jquery post is to check for $_SERVER['HTTP_REFERER'] variable in your PHP code to be same as the URL that has sent jquery post.
The easier way to do this would be to send a header with jquery that you later read with PHP. It's in no way a true protection, but it does prevent the users from sending requests without first inspecting the headers it's supposed to send.
For instance, in your jquery call:
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
},
success: function(data) {
}
});
And in your PHP:
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
header("HTTP/1.0 405 Method Not Allowed");
exit();
}

Jquery/PHP - Prevent user from browsing to locked content

I have this simple login script:
$.ajax({
type: 'POST',
url: 'authorize.php',
data: { username: user, password: pass },
dataType: 'json',
success: function(data) {
if (data.status == "loggedIn") {
//Logged in
} else {
//Not logged in
}
}
});
Where //Logged in is, how should I call the page that required the login? I could simply $.load the page, but then what was the point of verifying a login when the user could just browse to this file in the first place?
I'd suggest using PHP Sessions across all of these pages. Make a check on the page you're going to $.load that the user is actually logged in and set the user as logged in on the authorize.php page if successful.
This way, if a user looks at the page source and see's what you're loading, but when they try and access that page it won't do anything because you're checking to see if they've been logged in already.
It's a matter of presentation, you can just load a div on another file, you don't need to load the whole thing.
I use ajax to login and $.load to "bring" a div I have in a template file. It's just because it makes it easier when you need to change the design.
Remember that splitting the work into individual "pieces" makes it easier for you to change things. Imagine you have the same login box on 20 individual templates. If you change one, you have to change 19 more.
You can't prevent a user from doing anything with javascript (jquery), since it is client-side and easily disabled/changed etc.
What you can do is simply $.load the page like you say, but also have a check against the session on the loaded page that checks for an actual login before sending the content. You'd need to set some variable in the session as part of authorize.php to indicate a successful login.
To prevent data from being accessed, you should look into using .htaccess and Apache's mod_rewrite. Whenever a user requests a piece of possibly sensitive data, you'll invisibly call a PHP page which will then serve up either the requested data or a 403 Forbidden.
Example:
.htaccess
RewriteEngine On
RewriteRule ^user-content/(.+) display_content.php?file=$1
Then, any files that would be accessed in user-content will be rerouted through display_content.php. You can also use this .htaccess file to help prevent hotlinking by refusing to display the resource if there's a referrer.
display_content.php
<?php
if (isLoggedIn($_COOKIE["username"], $_COOKIE["password"]) && isset($_GET["file"])) {
if (mimeTypeOk($_GET["file"]) { // Implementation not shown
readfile($_GET["file"]);
exit();
}
}
header("403 Forbidden");
?>
In order to do this the most secure way, you are going to have to use both jQuery as a client-side way and PHP as a server-side way of checking if the user is logged in. You don't need to load the entire page with jQuery, just use the following code to load only a div portion:
$("#load_dom").click(function(){
$("#result")
.html(ajax_load)
.load(loadUrl + " #picture");
});
Then, as a security measure, use PHP to restrict access to the page, by checking $_SESSION vars like this:
if (!isset($_SESSION['userid'])) {
// user is logged in
} else {
// user is not logged in
die("You are not logged in.");
}

Obtain actual browser URL in PHP

I need to retrieve the actual URL that the user see's in their browser. I have an Ajax request running at page load. Hence, the regular $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"] expression returns the request URL of the Ajax request instead of the actual URL in the browser.
Any idea how to get this?
You could pass it up from javascript in your ajax request, using window.location.href.
Also, it's likely that $_SERVER['HTTP_REFERER'] will contain the browser's current location.
You could also try using $_SERVER['HTTP_REFERER'];. This might work, not 100% sure though.
You can't do that with server-side code, as there is no server-side variable that refers to what the client sees. The only thing you CAN see (and then again, it depends on the browser the user's using, some don't pass this info) is the HTTP_REFERRER variable. This however, is only set when a page calls another, not when users first access your site.
See this for more details.
A possible solution however, might be to use javascript function to send the browser's top URL to the server using an AJAX query, and to fire it client-side whenever a user loads the pages) you want to get this info for.
Edit: Damn, too slow, already answered!
Pass a hidden input that has the browser value set with your ajax request. Unless someone is being malicious, it should suffice.
If you do an Ajax-request, you could pass the address available through Javascripts window.location.href variable as a POST-variable with the request.
With jQuery it would be something like:
$.ajax({
url: 'your-url.php',
type: "POST",
data: { url: window.location.href },
success: function (data) {
// Do something on success
}
});
With such a request you could access the URL on the server-side with a simple:
<?php
$url = $_POST["url"];
?>
Actual Website Link in php
<?php
echo $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
?>
Server-side languages can't see what happens after they've rendered and outputted the page.

jQuery to post to php file

I have an index.html file which I want to run some jQuery when it is loaded. Essentially, I want to check to see if a user is already logged in based on some session variables.
So index.html will contain some jQuery which uses $(document).ready(function(){ });
In this function I want to just fire autheticate.php which checks to see if $_SESSION['user'] is set, if it is then it will redirect to home page otherwise it will redirect to login page...
how can I post in jQuery without having a html form? I just want to post to a url...
EDIT:
Based on #jondavidjohn's answer I changed my web app so that it uses index.php to check sessions:
<?php
session_start();
if(isset($_SESSION['username'])){
//go to home page
header('Location: ...home.html');
}else{
//go to login page
header('Location: ...login.html');
}
?>
It is surely possible doing this with javascript, but it is not secure at all...
You need to be checking at the server level for $_SESSION['user'] before you even send the content to the browser...
My answer would be to do the checking / redirecting with PHP before anything gets sent to the browser, it will be less complicated and more secure...
The reason a javascript solution is insecure is that you are relying on a technology that resides and is controlled by the client to control access to protected areas.
You can use $.post(url, params), where url is a string and params is a hash with your post data.
$.post("/authenticate.php",null,function(data){
// do something based on response returned
if($data){alert("authenticated");}
else
alert("not authenticated");
});
in your php file
if(isset($_SESSION['user']))
{
echo true;
}
else
return false;
Use $.post() to post data via AJAX to a page. Doing it this way won't allow the PHP script to redirect the user, you'll have to java JavaScript redirect them.
$.post('/path/to/page.php', {userID: 5}, function(data){
// Use window.location to redirect
});
Or, you can create a "fake" <form> element, and post that.
var $form = $('<form/>').attr({
method: 'post',
action: '/path/to/page.php'
});
var $input = $('<input/>').attr({
name: 'userID',
type: 'text'
}).val('5');
$input.appendTo($form);
$form.submit();
I suggest you take #jondavidjohn's advice, and have PHP redirect the user before the page is sent to the browser. That's much more secure.
Why bother with the AJAX request? Since you're building the page with PHP, just have PHP embed some variables in a JavaScript block:
<script type="text/javascript">
var is_logged_in = <?php echo $_SESSION['logged_in'] ? 'true' : 'false' ?>;
</script>
This'd save you an HTTP round-trip to retrieve data you already had available.

Categories