home *** CD-ROM | disk | FTP | other *** search
- Subject: CGI security: Escape newlines.
- X-To: bugtraq@CRIMELAB.COM
- X-cc: www-security@ns2.Rutgers.EDU
- To: Multiple recipients of list BUGTRAQ <BUGTRAQ@crimelab.com>
-
- When sending user-supplied data to a shell in a CGI program, it has
- become common practice among security-conscious CGI authors to remove
- or escape certain shell metacharacters to avoid them being interpreted
- by the shell and possibly allowing the user to execute arbritrary
- commands at his or her will.
-
- There are a good set of security guidelines at:
- http://www.cerf.net/~paulp/cgi-security/safe-cgi.txt:
-
- That document recommends removing or escaping the following characters
- in user-supplied data before passing it to a shell:
-
- ;<>*|`&$!#()[]{}:'"/
-
- There is (at least) one character missing from this list: the new line
- character. I have never seen the new line character included in a list
- of metacharaters to filter.
-
- A sampling of widely-available CGI programs turned up many that are
- vulnerable. Just about any CGI program which "un-hexifies" (converts
- characters represented by their hex values in a URL by to their actual
- character) its input and passes that input to a shell is likely to be
- vulnerable.
-
- Here's a toy example:
-
- #!/usr/local/bin/perl
- # usage: http://your.host/cgi-bin/echo?<string>
- # Echos back the QUERY_STRING to the user.
-
- $| = 1;
- $in = $ENV{'QUERY_STRING'};
- $in =~ s/%(..)/pack("c",hex($1))/ge;
-
- # Escape the nasty metacharacters
- # (List courtesy of http://www.cerf.net/~paulp/cgi-security/safe-cgi.txt)
- $in =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g;
-
- print "Content-type: text/html\n\n";
- system("/bin/echo $in");
-
- Install this program in cgi-bin/echo and
- <http://your.host/cgi-bin/echo?hello%20there>, will return a page
- containing the text "hello there".
-
- Insert %0A, the newline character, and you can exploit the shell
- to run any command you wish.
-
- For example, the URL <http://your.host/cgi-bin/echo?%0Acat%20/etc/passwd>
- will get you the password file.
-
- (In Perl, the call to system() should have broken up the arguments:
- system("/bin/echo", $in);
- and the problem would disappear.)
-
- While this example uses system() in Perl, the general program will
- show up whenever a shell is invoked.
-
- THE FIX:
-
- Very simple. Add the character \n (the new line character) to the
- list of characters to REMOVE from user-supplied data before
- suppling it to a shell in a CGI program.
-
- #!/usr/local/bin/perl
- # usage: http://your.host/cgi-bin/safe-echo?<string>
- # Echos back the QUERY_STRING to the user.
-
- $| = 1;
- $in = $ENV{'QUERY_STRING'};
- $in =~ s/%(..)/pack("c",hex($1))/ge;
-
- # Escape the nasty metacharacters
- # (List courtesy of http://www.cerf.net/~paulp/cgi-security/safe-cgi.txt)
- $in =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g;
-
- # SECURITY FIX: REMOVE NEWLINES
- $in =~ tr/\n//d;
-
- print "Content-type: text/html\n\n";
- system("/bin/echo $in");
-
- Again, this bug exists in MANY CGI programs. If you maintain CGI
- programs on your server, I suggest you check through each of them.
- I've only looked through several CGI programs, and found the bug on
- some of them (the authors have been contacted). If I have more time in
- the near future, I'll post a list of vulnerable programs as well as
- alerting he authors. In the meantime, you should check through the
- source of all of your CGI programs for this bug.
-
- --
- Jennifer Myers http://www.eecs.nwu.edu/~jmyers/
-
-