secure - Secure Programming
Programming securely is not difficult but it does require extra attention to specific details and a general knowledge of those details. This document describes three broad classes of secure programming topics and outlines many known issues in these classes. This document also contains many important and authoritative references for further information.
The intended audience for this document includes programmers and technical managers of projects described in the DESCRIPTION section below.
Because of the elevated potential for abuse, network and multi-user environments require that you (the programmer) use secure programming techniques. No programming language is inherently secure enough that programmers can ignore good security programming practices.
Perl is also not exempt from programmer-caused security problems. While Perl was designed with secure programming in mind and implements many important features to make data more trustworthy, it is easy for a programmer, because of Perl's flexible nature, to side-step Perl's built-in security features or to simply not enable others.
This document describes three classes of secure programming techiniques and principles:
Each section contains one or more topics related to the corresponding programming class. The number of resources for a particular topic does not imply the relative importance or unimportance of the topic. Resource lists are ordered by how broadly the resource addresses the problem as well as usefulness.
This section contains secure programming topics which apply to nearly all UNIX programming environments and languages, including Perl.
Commonly referenced resources for writing secure code. The book Building Secure Software is well-written with up-to-date examples and references. It contains sections on nearly all topics covered below in some detail, including some important aspects of Perl programming (taint mode is covered as well as taint mode's shortcomings).
John Viega & Gary McGraw, Building Secure Software (c) 2002 Addison-Wesley
David A. Wheeler, "Secure Programming for Linux and Unix HOWTO" <http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO.html> A thourough treatment of secure programming of all kinds.
Adam Shostack, "Security Code Review Guidelines" <http://www.homeport.org/~adam/review.html>
Thamer Al-Herbish, "Secure UNIX Programming FAQ" <http://www.whitefang.com/sup/secure-faq.html>
The Shmoo Group, "How to Write Secure Code" (a list of URLs, books, etc.) <http://www.shmoo.com/securecode/>
SecureProgramming.com (from John Viega, author of Building Secure Software) <http://www.secureprogramming.com/>
If you are writing a setuid/setgid program, begin by reading the following sources. Most exploits in UNIX come from an attacker being able to gain elevated privileges or causing a poorly engineered program to execute commands on the attacker's behalf.
Matt Bishop, "Writing Safe Setuid Programs" <http://nob.cs.ucdavis.edu/~bishop/secprog/index.html> A list of presentations and papers written by Matt Bishop regarding Setuid programs.
Matt Bishop, "How To Write a Setuid Program" <http://nob.cs.ucdavis.edu/~bishop/papers/Pdf/1987-sproglogin.pdf>
David A. Wheeler, "Secure Programming for Linux and Unix HOWTO" <http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO.html#MINIMIZE-PRIVILEGES>
Thamer Al-Herbish, "Secure UNIX Programming FAQ: Sections 3 & 4" <http://www.whitefang.com/sup/secure-faq.html#PRIVILEGES1>
COPS, "setuid(7)" <http://www.homeport.org/~adam/setuid.7.html> A man page with advice for setuid programmers.
"Direct SQL Command Injection is a technique where an attacker creates or alters existing SQL commands to gain access to unintended data or even the ability to execute system level commands on the host. This attack relies on exploiting nonexistent or poorly designed input validation routines." -- OWASP, Guide To Building Secure Web Apps.
For additional information on SQL injection vulnerability see the following resources:
OWASP, "A Guide to Building Secure Web Applications and Web Services" Chapter 11, "Preventing Common Problems" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82>
OWASP, "Direct SQL Command Injection" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82#owasp-id,N400BC6>
SQLSecurity.com, "SQL Injection FAQ" <http://www.sqlsecurity.com/DesktopDefault.aspx?tabindex=2&tabid=3>
This section contains secure programming topics which apply specifically to Perl.
The Perl man pages are indispensible resources for learning how to program in Perl securely.
perlsec - Perl security
perlrun - how to execute the Perl interpreter
"Dispelling the Dweomer" in perlopentut and "File Locking" in perlopentut
perltrap - Perl traps for the unwary
perllexwarn - Perl Lexical Warnings
Jordan Dimov, "Security Issues in Perl Scripts" <http://www.cgisecurity.net/lib/sips.html>
Taint mode is a special runmode in Perl that performs a variety of security checks before running your program. Perl enables taint mode in two circumstances: when the program is running with different real and effective user or group IDs or when you explicitly enable taint mode by using the -T command line flag (see perlsec for details on how taint checking works).
Perl's "use warnings" pragma (and -w switch) enables Perl's internal warning system, which prints warnings for special unsafe conditions (like unused variables, variable use before declaration, redefined subroutines, data type mismatches at runtime, deep recursion, and many others).
The principle authors of Perl (Larry Wall, et. al) express their own opinion on the warnings pragma in perl:
DIAGNOSTICS
The "use warnings" pragma (and the -w switch) produces
some lovely diagnostics.
See the perldiag manpage for explanations of all Perl's
diagnostics. The "use diagnostics" pragma automatically
turns Perl's normally terse warnings and errors into these
longer forms.
...
Did we mention that you should definitely consider using
the -w switch?
BUGS
The -w switch is not mandatory.
...
See perllexwarn for information about the warnings pragma which can be used like the strict pragma and does not leak across package boundaries (as -w does). This is now the preferred method of enabling warnings (versus the -w switch).
By enabling warnings in your programs and modules you will be alerted to many programming bugs before they become security exploits (all security exploits are caused by programming bugs at some level or another).
Perl's strict pragma enforces certain programming strictures which help avoid hard-to-track-down errors as well as some dangerous practices (passing program control to symbolic references, etc.).
perldsc (Perl's Data Structures Cookbook) encourages all programmers to always "use strict" at the top of modules and programs because it helps to catch accidental "symbolic dereferencing", among other common mistakes.
If you find your program doesn't run cleanly under "use warnings" and "use strict", it is likely your program could use some refactoring to eliminate some of the dangerous (or at least unorthodox) practices that might plague it.
The reason for enabling stricture is the same for that as warnings: you will be alerted to many programming bugs before they become security exploits (all security exploits are caused by programming bugs at some level or another).
Performance under "use strict" and "use warnings" often improves because of the enforcement of explicitly declared lexical variables and properly initialized package variables.
Perl is an excellent "glue" language: it allows you to run system applications, save the output of those applications, and do this in a variety of ways.
However, you should take care to ensure that the external program being run is the one you think it is and that it is receiving the arguments you think it should. Perl's taint mode will always help you discern when your program may be executing or using untrustworthy data, but these techniques will also help you avoid other pitfalls.
An excellent resource describing many Perl gotchas for CGI:
Lincoln Stein and John Stewart, "The World Wide Web Security FAQ" <http://www.w3.org/Security/Faq/wwwsf4.html>
Both system and exec take lists as arguments. When possible, use the two (or more) element list argument form for both of these functions. From "exec" in perlfunc:
If there is more than one argument in LIST, or if
LIST is an array with more than one value, calls
execvp(3) with the arguments in LIST. If there is
only one scalar argument or an array with one ele-
ment in it, the argument is checked for shell
metacharacters, and if there are any, the entire
argument is passed to the system's command shell
for parsing (this is "/bin/sh -c" on Unix plat-
forms, but varies on other platforms). If there
are no shell metacharacters in the argument, it is
split into words and passed directly to "execvp",
which is more efficient.
Not only is execvp far more efficient than forking a subshell, it it also safer because subsequent arguments will not be passed to the shell (and then interpolated according to shell rules).
Unless you are absolutely certain the backtick command will not be interpolated mistakenly (i.e., you are using a full path to any programs in the backtick and all variables, if any, have been explicitly untainted), consider a safe backtick (or pipe open) as described in "Safe Pipe Opens" in perlipc.
When you want to read data from a program and you're running with elevated privileges (or even under reduced privileges), consider using a safe pipe open, described in "Safe Pipe Opens" in perlipc.
File locking is a necessity when concurrent processes read from or write to a shared file. The following resources provide more information and examples of effective file locking.
Kevin Meltzer, "File Locking" <http://perlguy.com/articles/locking.html> introduces semaphores as a means of locking resources
Locking Berkeley DB files for concurrent access requires different semantics than normal file locking and it is not as simple as some of Perl's man pages might have suggested in the past.
Bundled with Perl 5.6.1 is a new DB_File module man page that recommends flock not be used (at least directly) when locking Berkeley DB files because the inital block of the DB is cached during open (before the lock is obtained). This leads to all kinds of race conditions and corruption problems.
Please see "Locking: The Trouble with fd" in DB_File of a Perl 5.6.1 or later distribution.
This section contains secure programming topics which apply specifically to CGI and Web programming.
Lincoln Stein and John Stewart, "The World Wide Web Security FAQ" <http://www.w3.org/Security/Faq/wwwsf4.html>
OWASP, "A Guide to Building Secure Web Applications and Web Services" <http://www.owasp.org/documentation/guide/1.1/index> Exhaustive and well-organized with practical examples of what to do (and avoid) when writing web applications.
www.cgisecurity.com, (list of CGI/Web programming resources) <http://www.cgisecurity.net/lib/>
With the rise of freely available software comes a proportional rise in poorly written software. Most CGI authors do not intend to flood the Web with security-hole laden programs; most authors have noble intentions of providing a useful piece of software that achieves its purpose well.
However, because of the large volume of scripts and the relatively small number of competent programmers available, hundreds of the most popular scripts available have significant security flaws ranging from denial of service attacks to arbitrary command execution to root shell access.
Caution should be exercised when choosing any software (commercial or free); considerations such as software maturity, security trackrecord, incident response times, and vendor history can be important indicators as to how the software will fare in a production environment.
The BugTraq mailing list (http://online.securityfocus.com/archive/1) is an excellent resource to keep current on both commercial and free software security problems.
From CGISecurity.com:
"Cross site scripting (also known as XSS) occurs when a web application gathers malicious data from a user. The data is usually gathered in the form of a hyperlink which contains malicious content within it. The user will most likely click on this link from another website, web board, email, or from an instant message. Usually the attacker will encode the malicious portion of the link to the site in HEX (or other encoding methods) so the request is less suspicious looking to the user when clicked on. After the data is collected by the web application, it creates an output page for the user containing the malicious data that was originally sent to it, but in a manner to make it appear as valid content from the website." -- CGISecurity.com, <http://www.cgisecurity.com/articles/xss-faq.shtml>
For additional information on cross-site scripting see the following resources:
CERT, "Understanding Malicious Content Mitigation for Web Developers" <http://www.cert.org/tech_tips/malicious_code_mitigation.html>
CGISecurity.com, "Cross Site Scripting FAQ" <http://www.cgisecurity.com/articles/xss-faq.shtml>
OWASP, "Attacks on the Users" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82#owasp-id,N400AEE>
The following references describe various problems common to CGI programs and which have to do with trusting user input.
CERT, "How To Remove Meta-characters From User-Supplied Data In CGI Scripts" <http://www.cert.org/tech_tips/cgi_metacharacters.html>
rain.forest.puppy, "Perl CGI problems" Phrack Magazine, Vol. 9, Issue 55 <http://www.phrack.org/phrack/55/P55-07>
OWASP, "Attacks on the System" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82#owasp-id,N400BC1>
OWASP, "Path Traversal and Path Disclosure" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82#owasp-id,N400DE7>
OWASP, "Null Bytes" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82#owasp-id,N400E0E>
OWASP, "Canonicalization" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82#owasp-id,N400E7B>
OWASP, "URL Encoding" <http://www.owasp.org/documentation/guide/1.1/page.ptl?book=guide.1-1&chapter=N400A82#owasp-id,N400F3B>
This document may contain outdated links. Internal links to the Perl POD pages are known to be broken (but you should be able to locate them on your own system via perldoc, e.g., 'perldoc perlsec')
Scott Wiersdorf, <scott@perlcode.org>
Please read perlsec.