Preventing direct access to include files


#1

Hi everyone,

I have just begun playing with php includes; and I have a couple of questions that I would like help with:

  1. What are the ways to prevent direct access to include files stored centrally in one directory (e.g. includes)?

I’d like to know the different options–just for my own learning. From my reading, I have come across 3 methods:

Method A - Place the includes directory outside web accessible area.

Method B - Leave directory inside web accessible area, and use .htaccess to limit access.

Method C - Combine Method B with per-file blocking. (I am curious to learn how per-file blocking works - code examples, please.)

  1. Are there other ways? And which method is most secure and efficient?

  2. Can include files that contain no php (just pure html) have a .php extension?

All help will be gratefully received.

  • marsbar

#2

The most common approach I’ve seen for restricting access to PHP includes is to define a constant at the top of all your “entry points” (files that are meant to be loaded directly):

<?php define("IN_MARSBAR", 1); ...
and then to ensure it’s set at the top of all your included files:

<?php if(!defined("IN_MARSBAR")) { die("not an entry point"); } ...
Moving included files out of your web directory also works, it’s just harder to keep track of.


#3

Many thanks, andrewf, for your helpful reply.

A related question, please: using the common approach you described, what permission should be set for the includes directory and the files within?

Just in case anyone else is looking for the same answer, answer to question 3 in my original post is YES.

-marsbar


#4

If you’re using the approach I’ve described, the permissions on the includes directory don’t matter (so you can just leave them at the default). If you aren’t using the define() approach, you can set restrictive (750 or 700) permissions on the includes directory to get the same result.


#5

Thanks for your prompt help, andrewf.

If I understood you correctly, to prevent direct access to the includes, I can either adopt the define() method or just by setting restrictive permissions on the includes directory located within the web area.

Are there advantages to choose one method over another - or is the choice just a matter of personal preference?

If I placed the includes directory outside the web area, what permissions should it have?

  • marsbar

#6

The define() method is extremely useful for transportability - i.e. no need for checking access levels on a file/directory basis following a server move, or when installing your files onto another account somewhere, or publishing/selling your developed scripts online. If your scripts are solely for your own use, chmod’ing files/dirs to restrict access is a quick and secure alternative - as are htaccess allow/disallow directives placed within the include directory.

If the file/dir permissions allow the account user access privs you can locate your includes directory anywhere on the account (e.g. HOME/user/includes).

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#7

Many thanks for your helpful explanation, sXi.

Using the example given by andrewf, instead of returning the error message, is it possible to make the server return the normal 404 page? Any code example/explanation will be great!

-marsbar

P.S. Happy new year to everyone!


#8

If you mean via restrictive access, I think you might be able to customise your 403’s (maybe check the Wiki) - if not, one method on DreamHost might be to use a standard missing.html document and place restrictions on php files in your includes directory via .htaccess

  • Untested…

Standard missing.html (located in domain root)

[code]

404 Not Found

Not Found

The requested URL was not found on this server.

[/code] Restrictive [b].htaccess[/b] (located in includes directory)

ErrorDocument 403 http://[color=#0000CC]domain.com[/color]/missing.html <Files ~ "\.php$"> order allow,deny deny from all </Files>The .htaccess file above would deny access to *.php files and redirect to the missing.html document.

You could probably use ErrorDocument 403 http://domain.com to redirect back to main site.

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#9

Sorry, sXi; I should have been clearer: I meant preventing direct access via the define() method.

Recently DreamHost Code Monkey, andrewf, kindly provided the following example:

<?phpdefine(“IN_MARSBAR”, 1);…
and then to ensure it’s set at the top of all your included files:
<?phpif(!defined(“IN_MARSBAR”)) { die(“not an entry point”);}…

Instead of die(), is it possible to make the server return the standard error 404 page?

-marsbar


#10

You could try a header redirect.

<?php if(!defined("IN_MARSBAR")) { header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); } ...

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost


#11

Followed up with a die():

if(!defined("IN_MARSBAR")) { header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); die(); } ...Without that, you’ll end up generating a 404 page, and then continuing on as if nothing happened!


#12

Doh! Of course :wink:

Maximum Cash Discount on any plan with MAXCASH

How To Install PHP.INI / ionCube on DreamHost