PDA

View Full Version : phpInclude Help



Luke
03-05-2010, 12:32 PM
Hello

Before I say: Yes i've googled it, AND been in tutorials section; i can get it to work, but not the way I wanted it to and/or it errors.

Right, what I want is to have index.php?page=blablahere BUT I want something like ?page=operations/staff or ?page=community/members and I'd want that to load *.net/pages/operations/staff.htm or php
If you get me?
Else it would display index.php?page=404 (pages/404.htm)

Anyone shed some light?
Cheers
Luke

MattFr
03-05-2010, 12:42 PM
index.php?section=community&page=members
index.php?section=operations&page=staff

Then when including do the path like,


include "/pages/".$_GET['section']."/".$_GET['page'].".php";

All crap after the URL is bad anyway. Look into mod_rewrite.

Luke
03-05-2010, 02:42 PM
Managed to get it all working - cheers

Apolva
03-05-2010, 07:28 PM
index.php?section=community&page=members
index.php?section=operations&page=staff

Then when including do the path like,


include "/pages/".$_GET['section']."/".$_GET['page'].".php";

All crap after the URL is bad anyway. Look into mod_rewrite.

Make sure you verify the section/page against an array if you use this.

Luke
03-05-2010, 07:32 PM
^^ Explain?

This is my code:

<?php
if(!$_GET['page'] || $_GET['page'] == "home") {
include("pages/home.php");
}
elseif($_GET['page']) {
if($_GET['subpage']) {
if(!@file_exists("pages/{$_GET['page']}/{$_GET['subpage']}.php"))
{
echo "Not found.<br/><br/>The file could not be found - timmy must've ate it..";

}
elseif(@file_exists("pages/{$_GET['page']}/{$_GET['subpage']}.php")) {
include("pages/{$_GET['page']}/{$_GET['subpage']}.php");
}

} elseif(!$_GET['subpage']) {
/////
if(!@file_exists("pages/{$_GET['page']}.php") || $_GET['page']==404)
{
echo "Not found.<br/><br/>The file could not be found, please use the navigation next time";

} elseif(@file_exists("pages/{$_GET['page']}.php")) {
include("pages/{$_GET['page']}.php");
}

}
}
?>

LMS16
03-05-2010, 08:28 PM
^^ Explain?

This is my code:

<?php
if(!$_GET['page'] || $_GET['page'] == "home") {
include("pages/home.php");
}
elseif($_GET['page']) {
if($_GET['subpage']) {
if(!@file_exists("pages/{$_GET['page']}/{$_GET['subpage']}.php"))
{
echo "Not found.<br/><br/>The file could not be found - timmy must've ate it..";

}
elseif(@file_exists("pages/{$_GET['page']}/{$_GET['subpage']}.php")) {
include("pages/{$_GET['page']}/{$_GET['subpage']}.php");
}

} elseif(!$_GET['subpage']) {
/////
if(!@file_exists("pages/{$_GET['page']}.php") || $_GET['page']==404)
{
echo "Not found.<br/><br/>The file could not be found, please use the navigation next time";

} elseif(@file_exists("pages/{$_GET['page']}.php")) {
include("pages/{$_GET['page']}.php");
}

}
}
?>

I know the verify bit is important but if this is for a personal site then u obvs know the pages will exist...

Lew.

Luke
03-05-2010, 09:14 PM
It isn't a personal site

MattFr
03-05-2010, 10:22 PM
Basically that code would be pretty easy to exploit. This is pseudo because I can't be bothered to code, but do something like this:

switch section
case section 1:
switch page
case page 1, include page 1.
case page 2, include page 2.
default, show 404.
break
case section 2
switch page etc
break
default show 404.

Using this way, people can only get to pages you define. A better way to do this would be using a comparative array, but I cba to type that.

Apolva
04-05-2010, 12:17 AM
One way to verify:


<?php
// Usage: ?p=section/page
// Doesn't check if page name matches section name, but this doesn't really matter.

// Separate section from page, and put into two variables.
list($section,$page)=explode("/",$_GET['p'],2);

// Set the allowed page/section names in the arrays below.
$allowedSectionNames=array("sectionname1","section2");
$allowedPageNames=array("home","about");

$file="pages/".$section."/".$page.".php";
$matchedSection=false;
$matchedPage=false;

// Cycle through the possibilities - check if section / page name is allowed.
foreach($allowedSectionNames as $name){
if($section==$name) $matchedSection=true;
}
foreach($allowedPageNames as $name){
if($page==$name) $matchedPage=true;
}

// If either the section or page name is not allowed / doesn't exist, show four oh four.
if(!$matchedPage || !$matchedSection || !file_exists($file)) $file="page/404.php";

include($file);
?>
Haven't tested, but that should work + be secure.

But mod_rewrite is really more suited to this job.

Agnostic Bear
05-05-2010, 04:06 AM
The code was secure enough as it was. It doesn't need changing.

MattFr
05-05-2010, 03:03 PM
The code was secure enough as it was. It doesn't need changing.
Are you serious?

Apolva
05-05-2010, 03:40 PM
The code was secure enough as it was. It doesn't need changing.

You call this secure ?
include("pages/{$_GET['page']}/{$_GET['subpage']}.php");

Blob
05-05-2010, 04:14 PM
<?php
// File include by Blob off of HabboxForum
$config = array("default" => "home", // Default Page
"directory" => "pages/", // Directory where files are held (with trailing slash)
"restricted" => array( "index" ), // Restricted pages
"404" => "404.php" // Error Page (with trailing .php)
);
$page = ( ( $_GET["page"] ) === null ) ? $config["default"] : ( str_replace("/", "", ( ( ( in_array( $_GET["page"], $config["restricted"] ) ) !== false ) ? $config["default"] : $_GET["page"] ) ) );
( file_exists( $config["directory"] . $page . ".php" ) !== false ) ? include( $config["directory"] . $page . ".php" ) : include( $config["directory"] . $config["404"] );
?>

should work.
default = default page you want to load up
directory = directory where pages are, so if you have pages/home/index.php and pages/about/index.php you would do pages/
restricted = pages that arent allowed to be loaded
404 = 404 page

if you set it to pages/
page.php?page=pageHere
will include pages/pageHere.php
or if you have pages/home/index.php
page.php?page=home/index should work, haven't tried it

Agnostic Bear
05-05-2010, 05:36 PM
You call this secure ?
include("pages/{$_GET['page']}/{$_GET['subpage']}.php");

Yes. How is it not secure?

MattFr
05-05-2010, 06:38 PM
Yes. How is it not secure?

Lmao. Do you know anything? You could easily include anything, including restricted content with that.

Agnostic Bear
05-05-2010, 06:39 PM
Update:


<?php
define( 'CHECK_FOR_FORBIDDEN_FILES', true );
define( 'CHECK_FOR_FORBIDDEN_FOLDERS', true );
define( 'FORBIDDEN_FILE_LIST', 'index,secret,tuesday' );
define( 'FORBIDDEN_FOLDER_LIST', 'config' );

define( 'ERROR_FOLDER', './' );
define( 'ERROR_PAGE', 'error' );
define( 'CHECK_FOR_CONFIG_FILES', true );

$folder = ( isset( $_GET[ 'folder' ] ) === true ) ? $_GET[ 'folder' ] : ERROR_FOLDER;
$page = ( isset( $_GET[ 'page' ] ) === true ) ? $_GET[ 'page' ] : ERROR_PAGE;

$file = new handleLink( $folder, $page );
if( $file->theLink !== false ) {
include( $file->theLink );
} else {
include( ERROR_FOLDER . ERROR_PAGE . '.php' );
}

class handleLink
{
public $theLink;

public function __construct( $folder, $page )
{
$page = ( $this->_isValidPage( $page ) === true ) ? $page : $this->_filterPage( $page );
$folder = ( $this->_isValidFolder( $folder ) === true ) ? $folder : $this->_filterFolder( $folder );

if( $this->_checkForValidPage( $folder, $page ) === true ) {
$this->theLink = $this->_buildUrl( $folder, $page );
} else {
$this->theLink = false;
}
}

private function _checkForValidPage( $folder, $page )
{
if( file_exists( $folder . '/' . $page . '.php' ) === true ) {
return true;
} else {
return false;
}
}

private function _buildUrl( $folder, $page )
{
return $folder . '/' . $page . '.php';
}

private function _filterFolder( $incoming )
{
if( CHECK_FOR_FORBIDDEN_FOLDERS === true ) {
if( is_string( FORBIDDEN_FOLDER_LIST ) === true ) {
$str = explode( ',', FORBIDDEN_FOLDER_LIST );
} elseif( is_array( FORBIDDEN_FOLDER_LIST ) === true ) {
$str = FORBIDDEN_FOLDER_LIST;
} else {
exit( 'Oh no invalid forbidden folder list.' );
}

foreach( $str as $forbidden ) {
if( stripos( $incoming, $forbidden ) !== false ) {
$incoming = str_ireplace( $forbidden, '', $incoming );
}
}
}

if( strpos( $incoming, '..' ) !== false ) {
$incoming = preg_replace( '#\.{1,}#', '.', $incoming );
}

return $incoming;
}

private function _filterPage( $incoming )
{
// File traversary (Only use pcre if we absolutely have to.)
if( strpos( $incoming, '..' ) !== false ) {
$incoming = preg_replace( '#\.{1,}#', '.', $incoming );
}

// Only valid file names (Who really uses the name ~*hello*~.php (yes it's valid))
$incoming = preg_replace( '#([^a-zA-Z0-9\-_]+)#', '', $incoming );

return $incoming;
}

private function _isValidFolder( $incoming )
{
if( strpos( $incoming, '..' ) === false ) {
return true;
} else {
return false;
}
}

private function _isValidPage( $incoming )
{
// First make sure we have something there.
if( strlen( $incoming ) === 0 ) {
exit( 'No url detected' );
}

// First check for forbidden characters and extensions yadda yadda.
$incomingCheck = preg_replace( '#([^a-zA-Z0-9\-_]+)#', '', $incoming );
if( strlen( $incomingCheck ) === 0 ) {
exit( 'No valid url detected.' );
}

// Anything with config in it.
if( CHECK_FOR_CONFIG_FILES === true ) {
if( stripos( $incoming, 'config' ) !== false ) {
$incoming = str_ireplace( 'config' , '', $incoming );
}

// Quick check to make sure we're all good
$incomingCheck = preg_replace( '#([^a-zA-Z0-9\-_]+)#', '', $incoming );
if( strlen( $incomingCheck ) === 0 ) {
exit( 'You are trying to access a config file. Stop that.' );
}
}

// Now we'll check for standard forbidden phrases!
if( CHECK_FOR_FORBIDDEN_FILES === true ) {
if( is_string( FORBIDDEN_FILE_LIST ) === true ) {
$str = explode( ',', FORBIDDEN_FILE_LIST );
} elseif( is_array( FORBIDDEN_FILE_LIST ) === true ) {
$str = FORBIDDEN_FILE_LIST;
} else {
exit( 'Oh no invalid forbidden file list.' );
}

foreach( $str as $forbidden ) {
if( stripos( $incoming, $forbidden ) !== false ) {
$incomingCheck = str_ireplace( $forbidden, '', $incoming );
$incomingCheck = preg_replace( '#([^a-zA-Z0-9\-_]+)#', '', $incomingCheck );
if( strlen( $incomingCheck ) === 0 ) {
exit( 'You are trying to access a forbidden file. Stop that.' );
}
}
}

// OK! We have no forbidden files.
// As far as we can tell it's not a forbidden file and it's a valid url!
}

if( strpos( $incoming, '..' ) === false ) {
return true;
} else {
return false;
}
}
}
?>
Go hog wild. Testing duration: about 20 seconds. Should work just fine and dandy.

Yes it's a joke (but it works!)


Lmao. Do you know anything? You could easily include anything, including restricted content with that.

That's a host problem, not a coding problem (well it sort of is, but it's not insecurity on the php end)
A good host should have open_basedir enabled so you can't wander off.
Any other files in your directory are your problem, not a problem of insecurity.

Luke
05-05-2010, 06:41 PM
Lmao. Do you know anything? You could easily include anything, including restricted content with that.

Yes, I'm a noob at PHP, but how does it allow to include anything? Such as?

Apolva
05-05-2010, 06:44 PM
You can read/execute any file on the server...

?page=..&subpage=file - would simply run: file.php

Or with null-byte poisoning:
?page=../../../secretfile.txt[null character here]
Would print the contents of any file (regardless of extension)

More info: http://php.net/manual/en/security.filesystem.nullbytes.php

Agnostic Bear
05-05-2010, 06:50 PM
You can read/execute any file on the server...

?page=..&subpage=file - would simply run: file.php

Or with null-byte poisoning:
?page=../../../secretfile.txt[null character here]
Would print the contents of any file (regardless of extension)

As said previously, hosts should enable open_basedir to keep people inside their own directories and out of the rest of the server. This is still a trivial host problem, mod_security should handle that issue too.

Apolva
05-05-2010, 06:53 PM
As said previously, hosts should enable open_basedir to keep people inside their own directories and out of the rest of the server. This is still a trivial host problem, mod_security should handle that issue too.


While it may stop you leaving your /www/ dir, you can still read "secret" files used by other scripts, plus files which usually need .htaccess authentication.

Luke
05-05-2010, 07:36 PM
Right. I don't really want to change the script, because, it also sets the title of the box



ontenttitle" class="title">
<?php

if(!$_GET['page']) {
echo "WELCOME TO JETENGLAND!";
}
elseif($_GET['page']) {
if($_GET['subpage']) {
$page_name = str_replace("_", " ", $_GET['page']);
$subpage_name = str_replace("_", " ",$_GET['subpage']);
echo strtoupper($page_name." - ".$subpage_name);
}
elseif(!$_GET['subpage']) {
if($_GET['page'] == "ADMINISTRATIONCENTRE")
{
echo strtoupper("ADMINISTRATION CENTRE");
}
else
{
echo strtoupper($_GET['page']);
}
}
}
?>


So, instead of getting rid of this, how could i use .htaccess so /page/$1/$2 = ?page=$1&subpage=$2
I tried it, but it wouldn't work :/

Luke

Agnostic Bear
05-05-2010, 07:37 PM
While it may stop you leaving your /www/ dir, you can still read "secret" files used by other scripts, plus files which usually need .htaccess authentication.

That's a design error, you shouldn't include protected files in a directory with dynamic inputs.

Apolva
05-05-2010, 07:45 PM
That's a design error, you shouldn't include protected files in a directory with dynamic inputs.

@Jwish Bear - What I'm saying is, /protected/ could be accessed through the exploit when it would usually require some kind of authentication.
Better to just fix the script, rather than relying on a safety net.

@LukeBateson, look into mod_rewrite here (http://www.workingwith.me.uk/articles/scripting/mod_rewrite). Some knowledge of regular expressions might come in handy.

Blob
05-05-2010, 07:58 PM
Just ignore my working script then :S?

Luke
05-05-2010, 08:04 PM
Just ignore my working script then :S?

Sorry Blob, but again, it's because of the title defining i prefer the "page" "subpage" script. Didn't mean to ignore it ;(

MattFr
05-05-2010, 08:56 PM
That's a design error, you shouldn't include protected files in a directory with dynamic inputs.

Stop arguing for the sake of arguing. The point is, it could (easily) be exploited, so why take the risk? It's quick and easy to make it secure, so there is no reason what so ever for not doing it.

Agnostic Bear
05-05-2010, 09:25 PM
if you're really that paranoid, use this:


$page = preg_replace( '#([^a-zA-Z0-9_-]+)#', '', $_GET[ 'page' ] );

Want to hide these adverts? Register an account for free!