PDA

View Full Version : [PHP] Basic PHP includes



djr33
09-08-2007, 11:38 PM
1) CODE TITLE: Basic PHP includes

2) AUTHOR NAME/NOTES: Daniel Ross

3) DESCRIPTION: This script will include various 'pages' of code into an existing page.

4) CODE:

START OF PAGE:
<?php
function inc() {
$inc = 'default';
$page = isset($_GET['page'])?$_GET['page']:$inc;
if (file_exists('includes/'.$page.'.txt')) {
$inc = $page;
}
include('includes/'.$inc.'.txt');
}
?>

LINE OF INCLUSION:
<?php inc(); ?>

This is very basic PHP for those of us who use it daily, but I just got a question from someone wanting to know how to use PHP includes. Rather than just telling them to use <?php include($_GET['page']); ?>, I suggest this because:
1. It error checks.
2. By doing so, it prevents hacking/XSS.


Anyway, it's not a standard thing for the library, but I know some people would find it useful.

Twey
09-09-2007, 12:20 AM
2. By doing so, it prevents hacking/XSS.
includer.php?page=..&#37;2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd%00/EDIT: Oh no, PHP has a built-in check for this, it's OK. It doesn't check it at the file_exists() level, however. It just translates NUL to literal '\0' from GET and POST. There may be a way around this, depending on site structure. I'm checking it out now.
/FURTHER EDIT: No, GET, POST, and cookies all seem to be safe.

djr33
09-09-2007, 01:01 AM
At least it gets around anyone just supplying a URL directly.

tech_support
09-09-2007, 03:04 AM
includer.php?page=..&#37;2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd%00/EDIT: Oh no, PHP has a built-in check for this, it's OK. It doesn't check it at the file_exists() level, however. It just translates NUL to literal '\0' from GET and POST. There may be a way around this, depending on site structure. I'm checking it out now.
/FURTHER EDIT: No, GET, POST, and cookies all seem to be safe.
I'm sure you can do this basename('myurlhere') to prevent going through directories.

djr33
09-10-2007, 02:18 PM
Makes a lot of sense, actually.


START OF PAGE:
<?php
function inc() {
$inc = 'default';
$page = isset($_GET['page'])?$_GET['page']:$inc;
$page = basename($page);
$page = strpos($page,'.')?substr($page,0,strpos($page,'.')):$page;
if (file_exists('includes/'.$page.'.txt')) {
$inc = $page;
}
include('includes/'.$inc.'.txt');
}
?>

LINE OF INCLUSION:
<?php inc(); ?>

Twey
09-10-2007, 08:34 PM
<?php
function inc() {
$page = isset($_GET['page'])
? $_GET['page']
: 'default';

if(strpos($page, '.') !== false
|| strpos($page, '/') !== false
|| !file_exists($page = 'includes/' . $page . '.inc.php'))
$page = 'includes/error.inc.php';

include($page);
}
?>You forgot that:You're including these files as PHP, so storing them with a .txt extension isn't safe (on most servers) since they may contain sensitive PHP code; strpos() will return 0 if the character is at the start of the string, which type-converts to boolean false, so you must always check its return value with non-type-converting operators (=== and !==). In this case, by prepending a . to the start of the path name one could bypass your check (and still access interesting files like .htaccess and .htpasswd).

djr33
09-10-2007, 09:08 PM
1. I assumed the included pages were html only, for different elements displayed in a div, based on the original request.. But for maximum compatibility/functionality, that's a good point.
2. Wouldn't (strpos(a,b)) when b does exist as the first character evaluate to true?
If not, then--
echo "" ? '' : (0 ? '' : 'PHP is weird.');
I know you would need to check it in some situations, if comparing, but didn't realize it actually returned as false if it was first, for all usable purposes...


Also, really, you don't need the basename() function now that I think about it. Simply use the older version of the code, and it will be sure the file exists before including. 1. You might want a subfolder of the target directory, and, 2. you can't hack with it anyway, so no need for security. Not like you'll really need to error correct your own links, or so one would hope...

Twey
09-10-2007, 10:36 PM
I assumed the included pages were html only, for different elements displayed in a div, based on the original request.Then the pages should be included as HTML, rather than processed with PHP. PHP is, however, more useful.
Wouldn't (strpos(a,b)) when b does exist as the first character evaluate to true?No. strpos() can return two types: boolean false, if the character is not found at all, or the position of the character in the string. The first position in an array, string, &c. in PHP is 0; therefore, the first character is at position 0.
If not, then--
echo "" ? '' : (0 ? '' : 'PHP is weird.');Not really. The indexing position is the same in most languages, but generally they have a less confusing "not found" value, such as null or -1.
Also, really, you don't need the basename() function now that I think about it.Not if you do it my way, with the path check.
Simply use the older version of the code, and it will be sure the file exists before including.No, even without the NUL bug it's possible to read any file on the filesystem that ends with .txt, which is a potential security risk. If you wanted subdirectories, it's possible to simply remove the check for /:
<?php
function inc() {
$page = isset($_GET['page'])
? $_GET['page']
: 'default';

if(strpos($page, '.') !== false
|| !file_exists($page = 'includes/' . $page . '.inc.php'))
$page = 'includes/error.inc.php';

include($page);
}
?>The check for . will prevent paths with .. in them. Another option is to do:
<?php
function inc() {
$page = isset($_GET['page'])
? $_GET['page']
: 'default';

if(strpos($page, './') !== false
|| !file_exists($page = 'includes/' . $page . '.inc.php'))
$page = 'includes/error.inc.php';

include($page);
}
?>This also allows files with dots in the path, whilst at the same time disallowing paths such as ../file and ././././file, the latter of which is a commonly-used measure for bypassing buggy security systems. It's technically possible to have directories with . at the end of their names, but I've never seen one.

crespowu
01-11-2008, 02:46 AM
2. By doing so, it prevents hacking/XSS.

It sounds good.

Dazza30
02-07-2008, 01:58 PM
Hi

Im thinking about learning php, so if you dont mind me asking what does the code above actualy do?

boogyman
02-07-2008, 03:20 PM
<?php
function inc() {
$page = isset($_GET['page'])
? $_GET['page']
: 'default';

if(strpos($page, './') !== false
|| !file_exists($page = 'includes/' . $page . '.inc.php'))
$page = 'includes/error.inc.php';

include($page);
}
?>


Hi

Im thinking about learning php, so if you dont mind me asking what does the code above actualy do?

The code above is processing some page defined in a php file as $_GET['page'] or as it would appear in a browser address bar
http://www.dynamicdrive.com/index.php?page=_page_
If the file is in the correct format, the page / file will be brought into (included) the php file, if not, an error page will be included.