views:

414

answers:

8

I was going to ask what the best way to do this is, but then decided I should ask whether or not it is even necessary. I have never seen it done in JSP development, but it appears to be common practice in PHP. What is the reasoning behind this, and if I do not protect against this, what else should I be taking into consideration?

+1  A: 

Well, This is to prevent sensitive includes from being sent to the web-server directly. It's certainly not an all-inclusive security measure, but it could help with your particular setup.

If however, your user was in a position to include the file from their own script, it won't help at all

Issac Kelly
A: 

It also isn't just a security feature in php but more of how many MVC based PHP sites function. If for example in SugarCRM you were to call a module file directly the page load would fail because the controller, view and model were not previously loaded and you'd have no db config/connection information either, so to make sure all dependencies are loaded the users is forced through a known entry point - i.e. index.php

typemismatch
+1  A: 

I emit a 404 page, not as a serious security measure but only because I don't like leaking information about the internals of a site, even the names of internal files.

But if the file just contains functions then there's no real harm in omitting the check.

A: 

I just found an approach in the .Net MVC system that you could replicate for PHP using Apache Rewrites, .htaccess files or if you are using IIS, a web.config file.

As the MVC pattern doens't need the user to directly access aspx files these are not served and a 404 is sent instead. If you have a naming convention for included files "inc.php" for example you could redirect *.inc.php requests to a 404 for specific folders - in Apache Rewrite supply R=404 at the end of the rule will return that HTTP status to your client.

Some of these examples may help: Apache Rewrite Examples

Paul Shannon
+4  A: 

The reason this is more common in PHP than other similar languages has to do with PHP's history. Early versions of PHP had the "register_globals" setting on as a default (in fact, it may not have even been a setting in really early versions). Register_globals tells PHP to define global variables according to the query string. So if you queried such a script thusly:

http://site.com/script.php?hello=world&foo=bar

... the script would automatically define a variable $hello with value "world" and $foo with value "bar."

For such a script, if you knew the names of key variables, it was possible to exploit the script by specifying those variables on the query string. The solution? Define some magic string in the core script and then make all the ancilliary scripts check for the magic string and bail out if it's not there.

Thankfully, almost nobody uses register_variables anymore, but many scripts are still very poorly written and make stupid assumptions that cause them to do damage if they are called out of context.

Personally, I avoid the whole thing by using the Symfony framework, which (at least in its default setup) keeps the controllers and templates out of the web root altogether. The only entry point is the front controller.

Nathan Strong
This was some great information. Thanks Nathan!
hal10001
+2  A: 

If you include everything from outside web root then it's not an issue as nothing can be loaded directly.

da5id
I wrote a framework where everything but index.php was below doc_root... I don't understand why no one else does this. Its safer and to me cleaner then having to worry about if one of my config files could be read accidentally.
David
Same. It's always seemed like a no-brainer to me too, but this is the second time I've advised including from outside web root on this site alone!
da5id
Must be a david thing? :)
David
A: 

As already mentioned in some of the other answers, you shouldn't need to do this. If a file isn't supposed to be served up by the web server, you shouldn't leave it within the web folder. Includes should be placed in a directory outside the web root.

Apart from that, the proper way to tell the user that a page doesn't exist, is by emitting a status 404, using:

header("HTTP/1.0 404 Not Found");
exit;

If you don't do this, it is hard for non-humans (Eg. search-engines) to distinguish between a regular page and a non-page.

troelskn
A: 

This is very important because if you are editing your site running Google Toolbar, it will find your inner php files and then put them into search results. At best this will create an awkward experience for users but if you are a sloppy programmer, could reveal database connection information.