Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
CGI security is a frequent topic of dicussion on this site so I thought I'd raise another issue that illustrates a variety of problems that people face when trying to write secure scripts. The following example is rather simple, but helps to illustrate the dangers involved (my information came from this Phrack article. tilly originally supplied me with the link).

I'm posting this here in part so that I can archive this and link to it from my online CGI course. I figured it would be a handy way to get people to use Perlmonks more :)

Consider the following code:

#!C:/perl/bin/perl.exe -wT use strict; use CGI; # Do not run this script on a server connected to the 'Net # It is supplied as a bad example my $cgi = CGI->new(); my $file = $cgi->param( 'file' ); # Bad taint checking! # This is, amongst other things, a deliberately incomplete list # of shell metacharacters my $data = $1 if $file =~ m#([^./\\`$"'&]+\.?[^./\\`$"'&]+)$#; $data .= '.dat'; my $userInfo; open FILE, "<$data" or die "Cannot open $data: $!\n"; { local $/; $userInfo = <FILE>; } close FILE; print $cgi->header, $cgi->start_html, $cgi->pre( $userInfo ), $cgi->end_html;
Hmm.... what's wrong with it? The author (me) uses warnings, strict, and taint checking. Users need to be able to get at the contents of .dat files on the server, but filenames can be very unpredictable. This script allows them to view those files from any browser. Therefore, we need to (gasp!) let user data near the shell.

The author, however, knows this is a security hole, so he conventiently supplies a list of shell metacharacters which he doesn't want. Further, he appends a ".dat" extension to guarantee that the user can only view files with said extension. Looks pretty secure to me!

I deliberately left the list of shell metacharacters incomplete so Monks wouldn't be tempted to use this technique.

So what's the problem? Perl, as many of you know, is written in C. C recognizes the null byte (ASCII zero) as the end of a string. Perl does not. If Perl tries to make a system call (such as open FILE, $somefile) with an embedded null byte in the data, the data is passed to the C underbelly, which happily ignores any information from the null byte on. So how does that affect our script?

I named the script insecure.cgi and ran it locally through a browser. I used the following URL:

http://localhost/cgi-bin/insecure.cgi?file=insecure.cgi%00loser!
See that embedded %00? Hmm... it's right after the name of my script. It passes our taint checking and Perl thinks it's trying to open insecure.cgi%00loser!.dat. However, the C underbelly tries to open insecure.cgi, and does! Then, the rest of the script happily dumps its source code to your browser.

This illustrates a couple of points:

  • Don't let user data near the shell.
  • If you must let user data near the shell, use taint checking and specify what you will allow!!!
  • Don't store data files in the same directory as your CGI scripts
Specifying what you won't allow forces you to go over everything that you missed and ensure that there are no security problems. How many would have guessed that ASCII zero would be a risk?

This node brought to you by the letter C

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just go the the link and check out our stats.


In reply to CGI Security and the null byte problem by Ovid

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-19 01:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found