block php page in public view. but still able to use by other page.
hi, I'm working on a website that has ajax live search(search.php) on it, search.php calls in from another php page to search in database, it works just fine, the problem is search.php can be typed in url and display all data from database. I tried googling it, still don't have clear idea how to solve it. I've read that it can be done in .htaccess, also by changing permission... I just want to be enlightened how to properly fix the problem. thanks
how I would do it would be by adding another $_POST variable to the form.. something like the following..
$.post('search.php', {search: 'search term', secret: 'ajax'}, function(r){
$(insert).html(r)
})
and then on the post page..
if(isset($_POST['secret']) && $_POST['secret'] == 'ajax'){
// do your submitting..
} else {
// display some kind of error message since the secret post wasnt found
}
Try something like this in the first lines of search.php file
/***************DO NOT ALLOW DIRECT ACCESS************************************/
if ( (strpos( strtolower( $_SERVER[ 'SCRIPT_NAME' ] ), strtolower( basename( __FILE__ ) ) ) ) !== FALSE ) { // NOT FALSE if the script's file name is found in the URL
header( 'HTTP/1.0 403 Forbidden' );
die( '<h2>Forbidden! Access to this page is forbidden.</h2>' );
}
/*****************************************************************************/
I solve the problem by having non-landing PHP pages live outside the public html folder, often in a /php or /lib folder just above the public html folder. This kind of assumes that all your landing pages include some form of bootstrap that sets up your include path to include the /php folder.
Another easy-ish solution is to have your landing php files set a value or constant, and have your includes refuse to execute if the value isn't set - This way you cannot execute the php file directly.
index.php
<?php
define(VALID_REQUEST, 1);
include "include.php"
...
include.php
<?php
if (!defined(VALID_REQUEST)) { exit; }
...
Try this make sure to place it at the top of the search.php page :D
if(basename(__FILE__) == basename($_SERVER['PHP_SELF'])) send_404();
function send_404()
{
header('HTTP/1.x 404 Not Found');
print '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'."\n".
'<html><head>'."\n".
'<title>404 Not Found</title>'."\n".
'</head><body>'."\n".
'<h1>Not Found</h1>'."\n".
'<p>The requested URL '.
str_replace(strstr($_SERVER['REQUEST_URI'], '?'), '', $_SERVER['REQUEST_URI']).
' was not found on this server.</p>'."\n".
'</body></html>'."\n";
exit;
}
Related
I have several folders on my domain, within each folder contains an index.php file that checks to see if the database connection passes or fails, if it fails, the page is redirected to a top level file (outside of all folders) called offline.php. This part works great. The basic format I'm using to redirect if the db is offline is:
if ( !$dbconnect ) {
header("Location: https://www.test.com/offline.php");
}
Then, within the offline.php page, I need to check to see which folder brought the user to the offline.php page, and display a unique message to the user - based on the folder that brought them to the offline.php page.
For example:
test.com/test1/index.php redirects to offline.php, the message would say 'test1 brought you to this page'
test.com/test2/index.php redirects to offline.php, the message would say 'test2 brought you to this page'.
In multiple browsers I've tried the following code, which always results in 'unknown uri':
$url = 'https://' . $_SERVER['HTTP_REFERER'] ;
if ( strpos($url,'test') !== false ) {
echo 'test';
} elseif ( strpos($url,'test1') !== false ) {
echo 'test1';
} elseif ( strpos($url,'test2') !== false ) {
echo 'test2';
} else {
echo 'unknown uri';
}
Suggestions?
EDIT
Due to the unreliable nature of HTTP_REFERER I've decided to put all of the conditions within the index.php page and forget about the offline.php page. A HUGE thank you to everyone who offered suggestions!
Why would you use redirects at all? They are heavy on the server, slow and just plain old unnecessary. Use a switch statement and have 1 controlling page instead of multiple folders and pages.
If you use the following code on your offline.php page, you can see all of the $_SERVER variables available (referring URL is in there)
echo '<pre>',print_r($_SERVER),'</pre>';
From there, you can take $_SERVER['HTTP_REFERER'] use a select case, or if then statement and accomplish your goal.
Based on some of your questions in the comments and people pointing out the use of $_SERVER['HTTP_REFERER'] being unreliable, you could do something like this instead.
On your index.php page with the dbconnect check, you could modify it to be something like this. header("Location: https://www.test.com/offline.php?org=".urlencode($_SERVER['REQUEST_URI']));
Then, on the offline.php,
$page = urldecode($_GET['org']);
$org = explode('/',$page);
echo $org[1] to get the first value after the slash, $org[2] would get the next value etc..
This is my situation:
1) a simple_php.php file in webroot folder
2) the users_controller.php in the app/controllers
3) the follow function in the users_controller.php :
function login_flat($user_id){
$user_data = $this->User->find('first', array(
'conditions' => array('User.id'=>$user_id)));
if($this->Auth->login($user_data)){
$this->Cookie->write('User.id', $this->Auth->user('id'), true, '+2 hour');
$this->Session->setFlash(__('Welcome back !', true));
$this->redirect(array('controller'=>'posts', 'action'=>'index'));
exit();
}
else{
echo 'ERROR!!';
exit();
}
}
(a simple function to login user. NOTE : I know it's not safe , but it's for test only)
Now, If I call via browser the function ( eg. www.mysite.com/users/login_flat/13 ) it WORKS ! but ... I need to call it via an other file, the simple_php.php located in the webroot of my domain.
I try with the php "header" function. It "call" (redirect) to the login_flat function , but the login not work !!! :(
Have any suggestion ? thx in advance.
P.S.
I'm using cakephp 1.2.6
------------- EDIT ------------------
I solve my trouble reading this:--> Solution
From the OP:
this is the code I uses for the redirect in the simple_php file :
header("Location:http://".$subdomain_locale.".".$site_subdomain.".com/users/login_via_app/".$user_id."");
Which will redirect to
/users/login_via_app/13
Which is the wrong url, as it should be redirecting to
/users/login_flat/13
Also be sure to put 'exit();' after sending the header and check that nothing else is output before that, otherwise your redirect won't work
And, please check if the $sudomain_locale and $site_subdomain variables contains the right value, or debug the whole URL using this, instead of performing the redirect;
echo "this is the URL that will be redirected to:<br>";
print_r("Location:http://".$subdomain_locale.".".$site_subdomain.".com/users/login_via_app/".$user_id."");
exit();
I have a php page which should be included in otherpage but no directly. Lets assume it as 1.php and the other page as 2.php
1.php
<?php
if($_SERVER['REQUEST_URI'] == "/1.php"){
header("Location:2.php");
}
else
{
//some code here
}
?>
2.php
<?php
include("1.php");
?>
this worked well on localhost/1.php and have been redirected to localhost/2.php
but this had made a problem with localhost/1.php?somegetmethod=data I found that anyone can access this page by typing ?something=something at the end of 1.php url. How to change the code which can redirect all url which starts with localhost/1.php
you could check if a substring is at a given position like this
if(strpos($_SERVER['REQUEST_URI'], "/1.php") === 0) {
this checks if the REQUEST_URI starts with /1.php (= is at position 0)
Use $_SERVER['PHP_SELF'] instead of $_SERVER['REQUEST_URI'].
try it:
if($_SERVER['SCRIPT_NAME'] == "/1.php")
$_SERVER['REQUEST_URI'] contains URI of requeted page, in yoour case it's 1.php?somegetmethod=data.
Change code like:
if(strpos($_SERVER['REQUEST_URI'], "/1.php") === 0){
header("Location:2.php");
}else{
//some code here
}
What you often see, for instance in MediaWiki, WordPress and many other such applications, is this:
1.php
if ( !defined( 'YOURAPPCONSTANT' ) ) {
// You could choose to redirect here, but an exit would make just as much
// sense. Someone has deliberately chosen an incorrect url.
echo "Cannot directly call this file.";
exit( 1 );
}
2.php
define('YOURAPPCONSTANT', 'It is defined');
include('1.php');
That way, 2.php is the entry of your application, regardless of the url used to reach it. I think this is a much safer and more flexible way, and it is used so often for a reason.
I have this bit of code at the beginning of my index.php file:
if ( !isset($_GET['cat']) )
die(header("Location: ?cat=top"));
Basically, if there is no category set, it automatically redirects to category "Top".
I have now noticed that Google added index.php, but it only displays the URL in the search results, instead of displaying the meta tags I've defined.
All the other pages are indexed perfectly fine, just not the index.php file. Any solution for this?
Thanks in advance!
PHP uses per default a 302 redirect when using header: Location.
This messes up with SEO as google doesnt swap the redirected location with the inital one. Try using
if ( !isset($_GET['cat']) ) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: ?cat=top");
die();
}
This should tell google to index the redirected location which has the meta info.
Function die is capable of printing out the text/string data, I have never seen calling a header within die.
The right approach should be:
if ( !isset($_GET['cat']) ) {
header("Location: ?cat=top");
die();
}
You can call exit; instead of die();.
I think there is no need of calling die() function. you can just call like
if ( !isset($_GET['cat']) )
header("Location: ?cat=top");
I am using jQuery load, to load some data from an external file like this:
$("#div1").load("test.php");
Now this works fine but I want users not to be able to visit test.php. In case they type in the URL test.php, get redirected to index.php
I tried this:
I inserted in my index: <? $fromIndex = true; ?> and this in my test.php file:
<?
$fromIndex = true;
if(!isset($fromIndex) || !$fromIndex) {
header("Location: index.php");
exit();
}
?>
The redirection works great if you visit test.php but the load doesn't work from index.php.
EDIT: Note: I wouldn't mind changing the test.php to .xml ? Or anything else that would help. The content I'm loading is few <option>'s
Can someone help me please?
Thanks alot
There's not really a way for you to prevent a user visiting a URL directly, and yet still allow AJAX access to that same URL. A simple way to dissuade them, though, would be to either A) send the response back as a JSON object (which makes it pretty useless when accessed directly), or B) append a GET parameter to the URL and perform your redirect when that parameter is absent.
$("#div1").load("test.php?ajax=1");
and
<?
if( !isset( $_GET['ajax'] ) || $_GET['ajax']!=1 ) {
header( "Location: index.php" );
exit();
}
?>
jQuery's AJAX functions all send a X-Requested-With header with the contents XMLHttpRequest. You can use this to do what you want, but don't use it as an anti-abuse feature - it's trivially defeated. It should only be used to be helpful to users who stumble across the URL, or to present them with a helpful error page instead of say, a JSON feed.