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).
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.
"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:
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.
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>
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.
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.
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.
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.
"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:
The following references describe various problems common to CGI programs and which have to do with trusting user input.
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, <email@example.com>
Please read perlsec.