Welcome Guest ( Log In | Register )



 
Reply to this topicStart new topic
> CMS103 - Securing Your Website, Keeping your included files from being accessed directly.
Rating 5 V
vujsa
post Jun 11 2006, 03:39 AM
Post #1


Absolute Newbie
Group Icon

Group: Admin
Posts: 884
Joined: 20-February 05
From: Indianapolis, Indiana, USA (Midwest)
Member No.: 2,714



I decided to write this article in respose to a possible security hole that was discussed here: http://www.astahost.com/creating-using-inc...php-t12200.html

See Also:
- http://www.astahost.com/cms101-content-man...sign-t7778.html
- http://www.astahost.com/cms102-content-man...ign-t11367.html

In the previous 2 articles describing how to create a simple CMS using the PHP include() function, I've discussed how using included files can save a webmaster a lot of time. The downside to using included files is that it is possible for sensitive data to be public accessable. For example, if a hacker was to access and read one of your included files, he may be able to find a security hole in your script. The best way to prevent these kinds of security leaks is to ensure that the contents of any included file can not be viewed direclty.

Generally speaking, if your included files have a file extention of .php, then they should be treated like a normal PHP file and plain text will not be displayed if the file is access directly. This is only true if you make sure that you use opening (<?php) and closing (?>) PHP tags in your included files. Otherwise, everything will be treated like plain text when accessed directly. This is how we can have PHP in one part of our file and HTML in another part of the same file.

The real issue comes up when a file extention other than .php is used like the .inc or include file extention. Usually, most servers don't automatically parse .inc files as PHP. This can be remedied using your .htaccess file.

Editing or creating the .htaccess file in the directory where you have saved all of your included files can tell the server to parse .inc files as PHP.

In .htaccess add:
CODE

AddType application/x-httpd-php .inc
AddType application/x-httpd-php .include



Basically, this tells the server to send all files with the extention .inc or .include to the PHP engine.

Now that the server thinks these are PHP files, anything inside of the PHP tags will not be sent to the browser without being parsed.

Already, we have made a great improvement in the security of our included files but more can and should be done.

ALWAYS BE SURE TO LEAVE A BLANK LINE AT THE END OF YOUR .htaccess FILE SO cPanel CAN ACCESS IT IF NEEDED!
========================================================

Checking to be sure that an included file is being accessed by it's parent script before sending it's contents will make it very difficult to be viewed directly and/or in raw form.

In order to do this quickly and easily, we'll used 2 related PHP functions, define() and defined().

The define() function should be used in the parent script, usually index.php.
The defined() function should be used in each of the included files.

Assuming that you understood the code in the first 2 articles listed above, here is how the code looks.
Modified code from http://www.astahost.com/cms101-content-man...sign-t7778.html

index.php
CODE
<?php
define( "MY_ACCESS_CODE", true );
?>

<html>
<head>
<title>My CMS</title>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" style="font-family: verdana;">
<table width="100%">
<tr>
<td colspan="2" bgcolor=silver>
<?php include("header.php"); ?> <!-- Used for Banner Advertising etc... -->
</td>
</tr>

<tr>
<td width="150" bgcolor=red valign="top">
<?php include("menu.php"); ?> <!-- Used for The Main Menu... -->
</td>

<td bgcolor=navy>
<?php include("main.php"); ?> <!-- Could be left out and actual content inserted instead. -->
</td>
</tr>

<tr>
<td colspan="2" bgcolor=purple>
<?php include("footer.php"); ?> <!-- Banner Ads, Copyright Info., etc... -->
</td>
</tr>
</table>
</body>
</html>


header.php
CODE
<?php
defined( 'MY_ACCESS_CODE' ) or die( 'Direct Access to this location is not allowed.' );
?>

<center>
    <a href="http://www.AstaHost.com" style="border-width: 2px; border-color: teal; font-size: 18pt; font-color: #FF0000;">Advertise Here!</a>
</center>


menu.php - Here is the real time saver! smile.gif
CODE
<?php
defined( 'MY_ACCESS_CODE' ) or die( 'Direct Access to this location is not allowed.' );
?>

<span style="font-color: lime;">Search Engines</span><br>
<a href="http://www.altavista.com" style="font-size: 8pt;"> ♦  Alta Vista</a><br>
<a href="http://www.excite.com" style="font-size: 8pt;"> ♦  Excite</a><br>
<a href="http://www.google.com" style="font-size: 8pt;"> ♦  Google</a><br>
<a href="http://www.lycos.com" style="font-size: 8pt;"> ♦  Lycos</a><br>
<a href="http://www.yahoo.com" style="font-size: 8pt;"> ♦  Yahoo</a><br>


main.php
CODE
<?php
defined( 'MY_ACCESS_CODE' ) or die( 'Direct Access to this location is not allowed.' );
?>

<p>
         Enter your main content here.  You can simple leave the include statement out of the template and enter the content for the page directly into the index.php.
Hope this proves usefull to everyone.


footer.php
CODE
<?php
defined( 'MY_ACCESS_CODE' ) or die( 'Direct Access to this location is not allowed.' );
?>

<center>
    © 2005 Acme Web Design Inc. - All Right Reserved.<br>
</center>


Now here is how it works:
define() defines a constant in PHP. This is like a variable in PHP but it will never vary.
CODE
define("HAPPINESS", "Hot apple pie.");
echo HAPPINESS;

Prints: Hot apple pie.

In our case, we only need to define that the constant named 'MY_ACCESS_CODE' is defined so we put true in the definition field of the function like so.
CODE
define( "MY_ACCESS_CODE", true );

We don't care if the constant has a value or not just that is has been defined. We define the constant in the file that calls all of the included files. This is the parent script. It is usually the one that is presented to the public like index.php.

Next we check to see if the constant named 'MY_ACCESS_CODE' is defined. We do this in our included files. Since the constant is only defined in the file that is supposed to request it, the requesting file is the only one that has direct access to the included file.
When we use the defined() function, we are not actually doing anything as a result of a true answer to the question. The question is of course is "Is 'MY_ACCESS_CODE' defined as a constant?". What we are actually doing is performing an action if the answer to the question is false. If the answer is false, then we kill the script with the die() function. This acts as the custom error message handle for all PHP functions.

So we check to see if the constant is defined. If it is then there is no error in the code and the code continues to the next line. If the constant is NOT defined then there is an error and the die() function takes over. The script will do whatever the die() function says and will then terminate. Nothing past the die() function will be used. This includes any HTML that resides below the die() function! So only the
CODE
defined( 'MY_ACCESS_CODE' ) or die( 'Direct Access to this location is not allowed.' );
need to be inside of the PHP tags (<?php and ?>).

I usually place the defined() function at the very begining of the file since it is the first thing I want to check but theoretically, it can be placed anywhere inside of the file and still work as long as it is not inside of a conditional statement which could cause it to be bypassed.
=====================================================

So by ensuring that all of your included files are parsable by the PHP engine and only allowing direct access to included files by parent scripts, you will greatly reduce the risk of security holes in your website. These methods as well as ensuring that your file permissions are set properly will make for a more secure site.

Additional security can be added to your website that range outside of this topic but include .htaccess settings which controls how the server will handle any file or file type you define.

I hope this information proves to be useful to everyone. cool.gif

vujsa
Go to the top of the page
 
+Quote Post
mastercomputers
post Jun 12 2006, 04:05 AM
Post #2


BUG.SWAT.PATROL
Group Icon

Group: Members
Posts: 626
Joined: 1-September 04
From: Auckland, New Zealand
Member No.: 27



Hey vujsa,

I have a concern about part of your code that is used in .htaccess.

The problem here is you're specifying .inc .include to be used by the PHP interpretter, it may not seem like a problem until you start wondering about what mime-type .inc or .include would originally use. Just because you specified that it should be handled by the PHP interpretter and said application/x-httpd-php what if this did not work?

In a situation where .htaccess could possibly fail (1:Million?), be overwritten (does happen), someone forgets to configure it, etc, these files are vulnerable to being viewed as plain/text (possibly?) and you don't want that. At least if you maintained the file extension of PHP, then it's a known mime-type by the server and it should not need to be told how it's handled, though older versions you had to still specify this.

I think it's better to call the file something like filename.inc.php rather than just filename.inc as you're not making it compatible across all servers doing this.

By allowing this other extension, although I know it was used prior (so was short hand coding and see how that went with compatibility), you now have to be aware of your doings, and that if you had to prevent someone creating a .php file from user input, you need to remember also using .inc .include as well and prevent that too.

To sum up what I'm saying, if it's PHP keep to PHP's extension, if it's PERL use PERL's extension, if it's HTML, etc, stick to that extension, same goes for those who like changing the PHP interpretter to handle .html files, it's not the best thing security wise or performance wise for that matter. Keep to what's known.

As a semi-related thing, also your code editors will display the right colour coding syntaxing if they knew the filetype correctly.

Apart from that your tutorial seems good, though you don't seem to handle situations where include fails. Include will commonly fail if the file does not exist or unreadable, so include('thisfile.php') or code_to(... handle it ...); or better an alternative to display in it's place or if no alternative, then obviously this might need to have been required using require(), where if this fails your script terminates at the point it failed with an allowable error to be displayed.

Another security bonus that you missed is that you can store your include files outside of the web root, meaning it's inaccessible from viewing it directly by it's link, which probably destroys the need for the defined() but better safe than sorry.

Cheers,

MC
Go to the top of the page
 
+Quote Post
vujsa
post Jun 12 2006, 05:14 AM
Post #3


Absolute Newbie
Group Icon

Group: Admin
Posts: 884
Joined: 20-February 05
From: Indianapolis, Indiana, USA (Midwest)
Member No.: 2,714



QUOTE(mastercomputers @ Jun 12 2006, 12:05 AM) *

I think it's better to call the file something like filename.inc.php rather than just filename.inc as you're not making it compatible across all servers doing this.
...
To sum up what I'm saying, if it's PHP keep to PHP's extension, if it's PERL use PERL's extension, if it's HTML, etc, stick to that extension, same goes for those who like changing the PHP interpretter to handle .html files, it's not the best thing security wise or performance wise for that matter. Keep to what's known.

Hey thanks for the reply MC. I completely agree with you this time. laugh.gif It absolutely drives me nuts to see people use the .inc extention for PHP includes. I don't mind it so much for a sub_extention but PHP should be PHP. I remember from PERL all of the different extentions used on a regular basis and it got had to keep track of everything.

The only reason I wrote the article was because I knew so many people use the .inc extention. I figured if they were going to use this method of naming files, they should at least try to add some security. I guess I forgot to add my disclaimer to the tutorial.
Disclaimer:
PHP files should use a .php file extention. If you choose not to follow this very simple rule, then at least add a few security measures to try and protect yourself.
laugh.gif

QUOTE(mastercomputers @ Jun 12 2006, 12:05 AM) *

Apart from that your tutorial seems good, though you don't seem to handle situations where include fails. Include will commonly fail if the file does not exist or unreadable, so include('thisfile.php') or code_to(... handle it ...); or better an alternative to display in it's place or if no alternative, then obviously this might need to have been required using require(), where if this fails your script terminates at the point it failed with an allowable error to be displayed.

Another security bonus that you missed is that you can store your include files outside of the web root, meaning it's inaccessible from viewing it directly by it's link, which probably destroys the need for the defined() but better safe than sorry.

I tend to not go into error handling in my tutorials. I usually add those functions after I nearly complete my scripts. I guess that I would have an easier time debugging scripts if I'd add the error handlers during the coding proccess.

I might look into doing a really detailed error handling tutorial sometime.

QUOTE(mastercomputers @ Jun 12 2006, 12:05 AM) *

Another security bonus that you missed is that you can store your include files outside of the web root, meaning it's inaccessible from viewing it directly by it's link, which probably destroys the need for the defined() but better safe than sorry.

Actually, I decided not to go into that option because I was afraid it could get confussing for some people. It is easy to forget about a file that is off the grid so to speak. But placing your sensitive files in non-web access directories is a great security measure. Most of use have been doing this exact thing with our .htpasswds files. I guess it is a rather simple concept but I consider it a more advanced security measure.

One additional note which MC touched on.
Setting your server to send HTML files through the PHP engine WILL have an effect on your website proformance. Even though the HTML files may not contain any PHP, the engine still has to read the entire file before it will release it to the browser. If your file doesn't have any PHP in it, it should be a HTML file. If your file has PHP in it, then it should be a PHP file.

vujsa
Go to the top of the page
 
+Quote Post
warallthetm
post Jul 9 2006, 05:31 PM
Post #4


Newbie [ Level 2 ]
Group Icon

Group: Members
Posts: 27
Joined: 9-July 06
Member No.: 14,399



I have seen it where html files have had php variables like index.html?id=test , was this done using htaccess to parse it as php, or is it some kind of client side scripting like javascript? I cant see why you would need to do this with an html? Can you explain?
Go to the top of the page
 
+Quote Post
Emerald Green
post Jul 10 2006, 12:05 PM
Post #5


Newbie [ Level 1 ]
Group Icon

Group: Members
Posts: 7
Joined: 10-July 06
Member No.: 14,415



QUOTE(warallthetm @ Jul 10 2006, 01:31 AM) *

I have seen it where html files have had php variables like index.html?id=test , was this done using htaccess to parse it as php, or is it some kind of client side scripting like javascript? I cant see why you would need to do this with an html? Can you explain?

They were probably PHP files (or a similar technology, like ASP or JSP) using a .html extension for whatever reason. I know that a certain book on PHP recommends naming your PHP files with .html extensions to mask your use of PHP, thereby making your site just a little tougher for hackers. But I have to agree with vujsa and mastercomputers - it's better to name files as what they are.

If they were static HTML files, they must have had some sort of client-side script using the variable(s). Plain HTML can't do anything with variables - it's a markup language, not a programming or even scripting language. As far as I know (but my knowledge here is small - correct me if I'm wrong), Javascript doesn't have a native function for extracting variables from a URL. You could write a script to do it manually, though, if you really wanted to.

Incidentally, forcing an extension to parse as PHP doesn't necessarily have to be done in .htaccess. If you have access to your server configuration file, you can add the option there, which will change the setting for your whole website, not just the folder you put .htaccess in. Changing the server configuration globally isn't always desirable or feasible (as, for instance, when you are using a free web host!) but it's more efficient than using .htaccess.
Go to the top of the page
 
+Quote Post
NoMore
post Nov 11 2006, 08:22 AM
Post #6


Member [ Level 2 ]
Group Icon

Group: Members
Posts: 53
Joined: 11-November 06
Member No.: 17,170



Really nice one smile.gif
good job there smile.gif
this is bater than my way
i use Get and Post chackers and only by moving or including the file its useable smile.gif
ill try this method later today smile.gif

NoMore
Go to the top of the page
 
+Quote Post
Feelay
post Jan 18 2008, 07:52 PM
Post #7


Kinda N00B
Group Icon

Group: Members
Posts: 208
Joined: 13-January 08
From: Sweden
Member No.: 27,579



Hmm =/

Before i edited my .htaccess it looked like this:

CODE
# This folder does not require access over HTTP# (the following directive denies access by default)Order allow,deny

Should it look like that =? (be empty)

Now this is how it looks:
CODE
# This folder does not require access over HTTP# (the following directive denies access by default)Order allow,deny

AddType application/x-httpd-php .inc
AddType application/x-httpd-php .include


I am using Wamp

By the way: Very Very good tutorial =)

This post has been edited by Feelay: Jan 18 2008, 07:55 PM
Go to the top of the page
 
+Quote Post
toby
post Jan 20 2008, 02:57 PM
Post #8


Premium Member
Group Icon

Group: Members
Posts: 479
Joined: 29-September 06
Member No.: 16,228



Nice tutorial, I'm more of a fixer than a make so there are plenty of ideas here for me.

Feelay try this. Note, as Vujsa said there is a blank line at the end.
CODE
# This folder does not require access over HTTP (the following directive denies access by default)#
Order allow,deny
AddType application/x-httpd-php .inc
AddType application/x-httpd-php .include
Go to the top of the page
 
+Quote Post
Feelay
post Jan 20 2008, 03:43 PM
Post #9


Kinda N00B
Group Icon

Group: Members
Posts: 208
Joined: 13-January 08
From: Sweden
Member No.: 27,579



toby, thats how mine looks, but i ment.. should it be so empty =?
Go to the top of the page
 
+Quote Post
toby
post Jan 20 2008, 04:15 PM
Post #10


Premium Member
Group Icon

Group: Members
Posts: 479
Joined: 29-September 06
Member No.: 16,228



Yeah, that just means the defaults/higher settings are good.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic

Collapse

> Similar Topics

Topics Topics
  1. .htaccess Files Usage(3)


 



- Lo-Fi Version Time is now: 22nd August 2008 - 05:19 AM