NAME

secure - Secure Programming

SYNOPSIS

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.

DESCRIPTION

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.

GENERAL PROGRAMMING SECURITY

This section contains secure programming topics which apply to nearly all UNIX programming environments and languages, including Perl.

General Resources

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).

setuid/setgid programming

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.

SQL Injection Vulnerability

"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:

PERL PROGRAMMING SECURITY

This section contains secure programming topics which apply specifically to Perl.

General Perl Programming

The Perl man pages are indispensible resources for learning how to program in Perl securely.

Perl's Taint Mode

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 'warnings' Pragma

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

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.

system, exec, backticks, open, and pipes

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>

system and exec

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).

backticks

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.

open and pipes

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

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.

DB 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.

CGI PROGRAMMING SECURITY

This section contains secure programming topics which apply specifically to CGI and Web programming.

General CGI Programming

"Canned" CGI Scripts

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

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:

Data Trustworthiness

The following references describe various problems common to CGI programs and which have to do with trusting user input.

CAVEATS

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')

AUTHOR

Scott Wiersdorf, <scott@perlcode.org>

SEE ALSO

Please read perlsec.