[LWN Logo]
[LWN.net]
From:	 tobozo tagada <tobozo@iol.ie>
To:	 bugtraq@securityfocus.com
Subject: PHPSlash : potential vulnerability in URL blocks
Date:	 15 May 2001 11:46:13 -0000

                                  sAvAte inc.
                            Serial Savate System

<[( advisory )]>---------------------------------------<[( 
 xxxxxxxxxxx2.adv.en


Program: PHPSLASH
Homepage: http://www.phpslash.org
Author Contacted: 15/apr/2001
Answer: 16/apr/2001 (ajayrockrock)
Patch : 16/apr/2001
Version tested: 0.6.1
Found by : tobozo


- Problem description:
  ~~~~~~~~~~~~~~~~~~~~

Url block type can access the filesystem when a path 
is 
specified by the administrator. 

The method used in Block_render_url.class does not 
check
if the $url variable contains a valid url scheme.

No parsing is really done to check integrity of the url 
scheme, neither the content of the url and file name.




- Impact:
  ~~~~~~~

If a path to a file is specified (ex : /etc/passwd), the 
file will be read and its content stored in the cache
exactly as if it was a remote file on a given url.


- Exploit:
  ~~~~~~~~

Login as admin with GOD permissions
Access the BLOCKS admin section 
(blockAdmin.php3) and
create a new block with the following information : 

Title : notTrusted 
Type : url 
Site Location : whatever 
Source URL : ./config.php3 
Expire Length : 0 
Owned by section : home
Data : (empty) 
Order number : whatever 

It will display the content of the config.php3 as text in 
the block of the main page. 

It might become an issue if blockAdmin.php3 gives 
add/edit/remove permission to some users that are 
not 
supposed to access the filesystem. 


Fix : 
~~~~~

Replace the function parse() in the 
Block_render_url.class tu
use parse_url() and a regex before sending $url to 
the file()
function.


  function parse($block_info) {

    $url = $block_info["source_url"];


    /* check for url structure before opening it (you 
don't want
      /etc/passwd to be validated here -- tobozo -- */
    $urlParts = parse_url($url);

    if( (empty($urlParts)) or (!$urlParts) ) {
      $this->output = "Block_render_url.class:: Parse 
error reading
 [$url]";

      return;
      }

    $scheme         = $urlParts[scheme];
    $HostName       = $urlParts[host];

    if(empty($scheme))  {
      $this->output = "Block_render_url.class:: Missing 
protocol declaration
[$url]";
      return;
      }

    if(empty($HostName)){
      $this->output = "Block_render_url.class:: No 
hostname in [$url]";
      return;
      }

    if (!eregi("^(ht|f)tp",$scheme)) {
      $this->output = "Block_render_url.class:: No 
http:// or ftp:// in
 [$url]";

      return;
      }


    /* have to silence 'implode' and 'file' because you 
don't want
    the errors showing up on the main page */
    $ary = @file($url);
    $size = count($ary);

    $string = @implode("",$ary);

    if (strlen($string) < 1) {
      $this->output = "Block_render_url.class:  $url 
contained no data.";
      return;
      };
    for ($i = 0 ; $i < $size ; $i++) {
      $output .= $ary[$i];
      };
    $this->output = $output;
   }





- Workaround :
  ~~~~~~~~~~~~

1) check for all possible protocols 
2) check for url content (host)


- Code:
  ~~~~~
Tested on http://assassine.org (successfully)

- Contact us:
  ~~~~~~~~~~~
http://madchat.sourceforge.net

tobozo@users.sourceforge.net

- Greetings:
  ~~~~~~~

The phpSlash Team, Gard, Jericho, madteam

[EOF]


http://www.iol.ie