stop direct access (.htaccess) and allow ajax request to subfolder - php

I am trying to stop direct access to a subdirectories and the php files within subdirectories. I've added the following code below to the .htaccess file within the subdirectories, however now the AJAX request are not working.
How can I stop access to www.example.com/subdir, but allow jQuery load & ajax functions to work?
Options -Indexes
order allow,deny
deny from all
Thank You

I would put apache directives aside, and -perhaps- focus on a php-based solution:
Make sure your file containing the jquery ajax call has a ".php" extension.
(of course inside that file, all jquery must be contained within <script> and </script> tags.
Inside your jquery function just before the ajax call, type that:
<?php $_SESSION["allow"] = "granted" ?>
(php tags run even if they are contained in "script" tags)
Open your ajax (php) file and at the very top type this:
<?php
session_start();
if((!isset($_SESSION['allow'])) && ($_SESSION['allow']!="granted")){die();}else
unset($_SESSION['allow']);
(...rest of your php code here...)
?>
... and you are Done!
P.S. Naturally, you may (or better: should) rename the sessions and give them different or more complex values, but I was just trying to point out the basic idea... Happy coding!

If your ajax function access some file that is inside that folder, you can't. As the AJAX is a requisition sent from the client browser.

Put this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
## disable direct access (but allow internal or AJAX requests)
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?domain\.com/ [NC]
RewriteRule ^subdir(/|$) - [F,NC]
Replace www.domain.com by your own domain name.
Note that this uses %{HTTP_REFERER} header to do this blocking and it is possible to manipulate this header value.

I found simplest solution using session.
project_folder
index.php
sub_dir
db_config.php
suppose you want to restrict direct access of your db_config.php,
you can do like this.
open your index.php from root and add this in first line of your code:
$sess = session_start();
$_SESSION["nuclear_weapon_key"] = "lolva";
now go to sub_dir -> open db_config.php
add this one the top of the page:
$sess = session_start();
if(isset($_SESSION['nuclear_weapon_key']) && $_SESSION['nuclear_weapon_key'] === "lolva"){ } else{ echo "LOL"; die();}
repeat this for whatever ajax/jquery containing file/s.
it worked for me.

You can use mod_rewrite to restrict access to all bet certain files in a directory. Add this to the .htaccess in that directory.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !(jsonp)|(ws)|(ajax)
RewriteRule .* - [R=404,L]
Just replace the jsonp ws ajax with the name of your files.

Related

Prevent access to php pages

Ok, so I have set the .htaccess like so:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)$ index.php
so as you can see I'm parsing everything to index except files because I need to "include" the php files and also displaying of images.
If users will type for example www.site.com/login.php that will show the login php page.
How do I prevent access to the php pages but also allow to "include" them?
Move them outside of your document root. They can be safely included from there but not accessed over the web.
If I understand the question do you want to not allow the user to go to other files if not logged in ? If so you can use php sessions to set a variable that they are logged in otherwise redirect to index
(If I understand the question)
If you wanna go that route (the outside webroot advise is the correct one!) then you could use a rule like that (see regex negative lookahead):
RewriteRule ^(?!index).+\.php$ - [F]
That's sloppy in that would allow index2.php or indexdir/xyz.php still; it just pevents anything that's not index*.php from being accessed. Make sure to also disallow .cgi or .phtml or .tpl if need be.

How to access a file via htaccess?

I have a folder structure like
Controller
|_check.php
View
|_ .htaccess
|_ index.php
|_ Webroot
|_ js
|_common.js
.htaccess
In .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ View/ [L]
RewriteRule (.*) View/$1 [L]
</IfModule>
In View/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
The outer .htaccess file links to View folder and there View/.htaccess links to index.php.
There is button in index.php(view file) with ajax to check.php.
I have given common.js The corresponding ajax function url as
var url = 'check.php'; // OR '../Controller/check.php'
The problem is the ajax is not working properly with two urls.
Whether I need change the folder structure to correct it or do I need to alter any htaccess file for accessing the check.php?
It's not about the folder structure but rather the htaccess rewrite rules that are wrong.
Your htaccess in the "root" redirects all requests to the View folder (which defaults to index.php, I assume)
I don't understand what you're trying to accomplish, if you explain I might be able to help you.
In your current setup, you can't access any file besides View/index.php (even when passing GET argument url)
EDIT:
In that case, if you wish to View/index.php be the only file accessible and force people to pass through View/index.php file, you can use PHP session variable.
Something like this...
in the top of your view.php file:
session_start();
$_SESSION['viewCheck'] = true;
//rest of view.php code
in your check.php code (or the file you're trying to access via AJAX)
session_start();
if (isset($_SESSION['viewCheck']) && $_SESSION['viewCheck'] === true) {
//Code of check.php
} else {
//Error message or redirect to view.php, for instance
//error message example
header('HTTP/1.0 401 Unauthorized');
//Redirect example
header("Location: http://www.yourhost.com/View/index.php");
}
NOTE 1:
You should remove the rewrite rules of your htaccess files.
NOTE 2:
Keep in mind that this is not bullet proof (and can be spoofed) since:
If someone visits View/index.php then he can access check.php freely. This can be mitigated if the session is killed after the ajax request. You can accomplish that if the ajax request consists in 2 requests, for instance, one to get a session key which expires in 10 seconds for instance, and then use that key to obtain the results from check.php
Session can be spoofed too (read more here)
Why dont you just set the path for the domain on the "View" folder, so noone can access you controllers etc. ?
I think this should also be more simple than playing around with .htaccess !
This is the way most PHP Frameworks do it..
And if you need to access the functions of check.php you can make a "ajax.php" that checks if the request is ok, and then uses "check.php" to catch the result!

PHP redirect when directly approaching?

I'm working on this PHP page wich includes different pages like header.php .
What I want is when you go to header.php, it redirects you to the homepage. I tried using header but when I include it, it keeps redirecting me.
I think it's possible with an if statement with $_SERVER, but I don't know how.
Anyone can help me out? Thanks in advance!
The best way to do this is to create a constant on your main landing page, so let say index.php is one of your main landing pages.
You would create a constant within there, and then do a check in all your sub templates that should only ever be included by a main page.
Example:
<?php
define("IN_VIEW",true);
require_once "header.php";
And then within header.php you can just to make sure that IN_VIEW is defined
<?php
if(!defined("IN_VIEW"))
{
die("Direct Access Forbidden");
}
//Header Here
If its not defined, then obviously the page has been loaded directly and not from index.php.
And then for every other "in-direct" page that should be secured you just place the three lines at the head of the file, and make sure the constant has been defined in your main pages (index,login,logout) etc.
if($_SERVER["PHP_SELF"] == "header.php") {
header("Location: index.php");
}
Although this isn't best practice. You shouldn't allow users to be able to access the PHP files in the first place. The simplest method of disallowing users access to this type of file is by moving the file above the document root, meaning it is impossible to request the header.php file via HTTP.
Another solution is to simply redirect everything to index.php so that direct access to any other script is prevented. On apache for example you can do this using .htaccess as follows:
RewriteEngine On
# redirect everything to index.php except exceptions
RewriteCond %{REQUEST_URI} !/robots\.txt$
RewriteCond %{REQUEST_URI} !/favicon\.ico$
RewriteCond %{REQUEST_URI} !/static/
RewriteRule ^(.*)$ index.php [L]
You can specify some exceptions such as your robots.txt file, and images directory.

what is the best way to do that name?get=

ok assume i have php page
has this name name.php?get= and has get varible named get
ok
how i can make it appear like that name?get=
If you are using apache, mod_rewrite is one way to go. There is a whole bunch of mod_rewrite tricks here.
I'd seriously reconsider before using (or overusing) mod_rewrite.
In almost all of my projects I use a simple mod rewrite in the .htaccess:
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./
AddHandler php5-script .php
This tells the server to forward all pages to / (index.php) unless a file otherwise exists.
In the root directory I have a folder called "views" with all of the pages that I use. E.g. the file used for /home would actually be /views/home.php. However, in the index.php I have a script that parses the user's url, checks for the file, and includes that.
$page = substr($_SERVER['REQUEST_URI'], 1);
if(!$page) :
header("Location: /home");
if(file_exists("views/$page.php")) :
include "views/$page.php";
else :
include "views/$page.php";
endif;
This creates a variable called $page that stores the value of everything in the URL after the domain name. I use a substr() function on the Request URI to get rid of the trailing forward slash (/) on the URL.
If the variable is empty, for example if the user is simply at http://example.com or http://example.com/ then it forwards them to /home, where the script then checks for the home.php file inside of the views folder. If that file exists, it includes it, and displays it to the user.
Else, the script will simply include the 404 page telling the user that the file doesn't exist.
Hopefully this helps you, and if you need any further explanation I'd be happy to help!
I think you're wanting to re-write the URL client-side, which would include mod_rewrite.
In the route of your website, create a file called .htaccess and place the following code in it:
RewriteEngine on
RewriteRule ^name?get=(.*) /name.php?get=$1
Now when you type http://www.example.com/name?get=something, it will actually map to http://www.example.com/name.php?get=something transparently for you.
As far as i could understand your question, you can not strip the file extension because otherwise it will not run. In other words, you can not change:
name.php?get=
into
name?get=
But if you mean to create links with query string values that you can put them in hyperlinks in this way:
Click here !!
If you're looking to create links using a variable '$get', then you can create the link like this:
<a href="name.php?get=$get>Link</a>
Or if you want to get the value of the query string variable, you can use this:
$get = $_GET['get']

How to stop direct execution of a php page using htaccess rules?

In my .htaccess file I have defined the following rule to make my register page URL as http://example.com/register/
RewriteRule register/ /register.php
The above rule is perfectly fine but I can access my register page from http://example.com/register/ as well as from http://example.com/register.php.
I don't want that user will be able to access the URL from http://example.com/register.php URL, is there any RULE which I can define in .htaccess to stop execution of register.php URL or simply redirect any direct register.php request to /register/
If you are doing this to avoid getting multiple links to the same content, you can simply don't use "register.php" anywhere on your page. I think no search engine will "guess" for a certain file type and if there are no security concerns you are on the safe side, because in my opinion no user will link to this file either. However if you want to be certain just reroute all your functionality through an index.php via one line in your .htaccess which should be placed inside your www-root directory:
RewriteEngine on
RewriteRule ^(.*?)$ index.php?file=$1
In your index.php you can then simply choose which function/file to invoke by breaking down and checking the $_GET["file"] parameter. To make 100% certain no one can access your register.php file directly just move it (and all your others) to a separate directory and include a .htaccess file with the following line:
DENY from all
There are a couple of other options to prevent direct access. Just define() a variable somewhere in your index.php and at the top of your register.php just put
defined('access') or die('Intruder alert!');
at the top. Another way could be to be honest and simply tell search engines that your content has been moved and that they no longer should use the old link:
header("Status: 301"); /* Content moved permanently */
header("Location: http://yourserver/Register/");
exit;
Update
Just one more thing that crossed my mind, you can also check $_SERVER["REQUEST_URI"], whether the user attached any ".php" and act accordingly by either denying access completely or just redirecting to the new location.
It is true that you cannot use location directive, but you can actually paste .htaccess file into any directory.
Just if you put this into it, say:
Options -Indexes
order allow,deny
deny from all
you can copy paste this file into any (root) directory you want to protect from external execution.
To check the initial requested URL path, you need to use the request line. So try this rule:
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php[/?\s]
RewriteRule (.+)\.php$ /$1 [L,R=301]
And then again your rule (in a slightly modified way):
RewriteRule ^register/$ register.php
If you want to completely block /register.php by using mod_rewrite, use a variant of SleepyCod's answer:
RewriteCond %{REQUEST_FILENAME} register\.php [NC]
RewriteCond %{IS_SUBREQ} false
RewriteRule .* - [F,L]
Explanation:
[NC]: Makes the condition case-insensitive, just in case you're on a windows box.
Condition 1: The requested filename is 'register.php', and
Condition 2: The request is no subrequest (this is important, since every new round through RewriteRules actually creates subrequests).
Rule: essentially do nothing
Flags: [F]: Send an 403 Forbidden header, [L]: This is the last rule to apply, skip all following rewrite rules
Rewriting correctly is an art by itself. I suggest you carefully read http://httpd.apache.org/docs/2.2/rewrite/.
Cheers,
Try this.
RewriteCond %{REQUEST_FILENAME} ^register\.php$ [NC]
RewriteRule ^/register register.php
Or this
Redirect register.php /register
Ignoring the user-experience part, you can implement the new rel=canonical link to sort out the search engines.
Although, for this case you should probably just use a 301 redirect from /register.php to /register/
In register.php
if ( stristr( $_SERVER['REQUEST_URI'], '.php' ) )
{
header ('HTTP/1.1 301 Moved Permanently');
header ('Location: /register');
}

Categories