tags:

views:

72

answers:

3

Hello,

I have certain files like header.php and footer.php. I would like to disable these files from being directly requested from the browser address bar.

If I have include 'file.php' in the code, then it should be included, but if it's directly requested, I don't want it to be shown since it serves no purpose. Is it possible?

Thanks in advance :)

+9  A: 

You can do any of these things, in order of desirability (from "good" to "it kind of works"):

  • Create them outside your web root. Example, assuming that /somepath/example.com/htdocs/ maps to http://example.com/:

/somepath/example.com/htdocs/index.php
/somepath/example.com/includes/header.php
/somepath/example.com/includes/footer.php

index.php:

<?php require_once('../includes/header.php') ?>
  • Prevent access via .htaccess

<Files (header|footer).php>
Deny from all
</Files>

  • (a hack if everything else fails) set a constant in the main file, die silently if not found.

index.php:

<?php define('INCLUDED_FROM_MAIN_FILE_EXAMPLE_COM',true) ?>

header.php:

<?php if (!defined('INCLUDED_FROM_MAIN_FILE_EXAMPLE_COM')) { die(); }

Piskvor
several good options +1
thetaiko
I think these suggestions are pretty much in order of desirability. The ideal is to keep files you don't want accessed directly completely outside of the web root.
Darryl H. Thomas
I wouldn't go down the road of relative paths, considering portability of code, but include a directive in the webserver configuration like (for apache) `php_admin_value include_path "/home/example.com/www/includes"` with a document root on `/home/example.com/www/pages` or something. Within your `/includes/` you can also make directories and then `include 'common/init.php'` for example.
mvds
@mvds: good point (although it actually makes the code *less* portable)
Piskvor
@Piskvor: interesting thought, kind of depends on the situation (try to move part of your project to a subdirectory!). But think of how you rarely see `#include "../this/that/important.h"` in C. At least I have never seen it.
mvds
@mvds: Moving project structure around is IMO less common than installing on a new server. Now you have to figure out the environment, plus you have one more config file to worry about.
Piskvor
Also, C's headers are source - they're compiled into code, not interpreted. As such, there are well defined entry points for a compiled C program (you can't launch a C program saying "start execution at the beginning of time.h", because there *is* no time.h in the compiled program), which can't be said of PHP.
Piskvor
all true, but having to worry *within each file* where the file is located relative to other files, with no apparent need, feels like mixing up concerns.
mvds
@mvds: Good point. Some projects solve this by defining PROJECT_BASEDIR in the config or at the entry point (which is basically another way of implementing your suggestion).
Piskvor
@Piskvor: that leaves only one reference to an absolute path within the project (or did you mean it is determined at runtime?!). Say you would chroot the whole thing, then you have 2 places to fix paths -- I'd still keep it very close to the definition of the document root. Besides, I think having a restricted include path is a security measure in itself (think of way back, the sysadmin having `.` in it's `$PATH`, and you having a special version of `ls` in your home dir...) but maybe php puts `.` in the include path regardless, I wouldn't know.
mvds
A: 

Why about renaming them as header.php.inc? And then setting

<Files *.inc>
    Order allow,deny
    Deny from all
</Files *.inc>

I think that's pretty standard.

leonbloy
That doesn't prevent the file from being served. But it probably prevents it from being parsed, which means you'll show the user the PHP code. Depending on the site, that could be a huge security risk. -- Never mind - the .htaccess code was added after I wrote this.
Scott Saunders
This would not prevent access to the file and could lead to exposure of the source code depending on the server's configuration. This technique *can* be used in conjunction with configuring the server to deny access to .inc files, but using the .inc extension defeats the convention of file extensions and would likely mess up syntax detection in editors, etc.If you instead use .inc.php and configure the server accordingly, you achieve the same desired effect without breaking things in editors, etc.
Darryl H. Thomas
+2  A: 

A common way of preventing that is creating a definition in index.php (or whatever you call it) and checking for that define.

That way you get something like this in your index.php

define('USING_INCLUDE', 1);

And this in your footer.php:

if(!defined('USING_INCLUDE')){
    header('HTTP/1.1 403 Forbidden');
    die();
}
WoLpH
I would do it excatly this way. But I would not only call `die()`, but also an http-header of 403 (access denied).
faileN
True faileN, I've changed it :)
WoLpH