
Many programs and libraries, including the shared library loader on both Unix and Windows systems, depend on environment variable settings. Because environment variables are inherited from the parent process when a program is executed, an attacker can easily sabotage variables, causing a program to behave in an unexpected and insecure manner [[Viega 03]].
Attackers can manipulate environmental variables to trick an executable into running a spoofed version of a shared library or executable. Most modern systems, for example, uses dynamic libraries and most executables are dynamically linked (that is, use dynamic libraries). If an attacker can run arbitary code with the privileges of a spoofed process by installing a spoofed version of a shared library and influencing the mechanism for dynamic linking by setting the LD_PRELOAD
environmental variable (or another LD_*
environmental variable). An interesting example of this vulnerability involving the RFC 1408/RFC 1572 Telnet Environment Option is documented in CERT Advisory CA-1995-14, "Telnetd Environment Vulnerability" CA-1995-14. The Telnet Environment Option extension to telnet supports the transfer of environment variables from one system to another, allowing an attacker to transfer environment variables that influence the login program called by the telnet daemon and bypass the normal login and authentication scheme to become root on that system.
Certain variables can cause insecure program behavior if they are missing from the environment or improperly set. As a result, the environment cannot be fully purged. Instead, variables that should exist should be set to safe values or treated as untrusted data and examined closely before being used.
For example, the IFS
variable is used by the sh
and bash
shells to determine which characters separate command line arguments. Because the shell is invoked by the C99 system()
function and the POSIX popen()
function, setting IFS
to unusual values can subvert apparently-safe calls.
Environment issues are particularly dangerous with setuid/setgid programs or other elevated priviledges, because an attacker can completely control the environment variables.
Non-Compliant Coding Example
This non-compliant code invokes the C99 system()
function without first sanitizing the environment. The C99 system()
function passes a string to the command processer in the host environment to be executed.
{quote
system(argv[1]);
Compliant Solution (POSIX)
Sanitize the environment by setting required variables to safe values and removing extraneous environment variables. Set IFS
to its default of " \t\n" (the first character is a space character). Set the PATH
environment variable to _PATH_STDPATH
defined in paths.h
. Preserve the TZ
environment variable (if present) which denotes the time zone (see the Open Group Base Specifications Issue 6 specifies for the format for this variable [[Open Group 04]]).
Risk Assessment
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
ENV03-A |
2 (high) |
2 (probable) |
2 (medium) |
P8 |
L2 |
References
[[ISO/IEC 9899-1999]] Section 7.20.4, "Communication with the environment"
[[Open Group 04]] Chapter 8, "Environment Variables"
[[Wheeler 03]] Section 5.2, "Environment Variables"
[[Viega 03]] Section 1.1, "Sanitizing the Environment"