Versions Compared

Key

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

...

An attacker who can fully or partially control the contents of a format string can crash the Perl interpreter, or cause a denial of service. She can also modify values, perhaps by using the %n|| conversion specifier, and use these values to divert control flow. Their capabilities are not as strong as in C [Seacord 20052005a], ; nonetheless the danger is sufficiently great that the formatted output functions {{sprintf() and printf() should never be passed unsanitized format strings.

...

This noncompliant code example tries to authenticate a user by having them supply the user supply a password , and only granting them access if only if the password is correct.

Code Block
bgColor#ffcccc
langperl
sub validate_password {
  my ($prompt, $password) = @_;
  my $is_ok = ($password eq "goodpass");
  printf "$prompt: Password ok? %d\n", $is_ok;
  return $is_ok;
};

my $host = `hostname`;
chop($host);
my $prompt = "$ENV{USER}\@$host";
if (validate_password( $prompt, $ARGV[0])) {
  print "$prompt: access granted\n";
} else {
  print "$prompt: access denied\n";
};

The program works as expected as long as the username user name and hostname host name are benign:

Code Block
user@host:~$ ./authenticate.pl goodpass
user@host: Password ok? 1
user@host: access granted
user@host:~$ ./authenticate.pl badpass
user@host: Password ok? 0
user@host: access denied
user@host:~$ 

However, the program can be foiled by a malicious usernameuser name:

Code Block
user@host:~$ env USER=user%n ./authenticate.pl badpass
user%n@host: Password ok? 0
user%n@host: access granted
user@host:~$ 

In this invocation, the malicious username user name user%n was incomprorated into the $prompt string. When fed to the printf() call inside validate_password(), the %n instructed Perl to fill the first format string argument with the number of characters printed. This caused Perl to set the $is_ok variable to 4. Since it is now nonzero, the program incorrectly grants access to the user.

...

This compliant solution avoids the use of printf(), since print() provides sufficient functionality.

...

The CERT Oracle Secure Coding Standard for Java: IDS06-J. Exclude user input from format strings

http://cwe.mitre.org/: http://cwe.mitre.org/data/definitions/134.html, "Uncontrolled Format StringMITRE CWE: CWE-134, "Uncontrolled format string"

Bibliography

Full-disclosure: Christey, Steven M. [Christey 2005] Format String Vulnerabilities in Perl Programs Fri Dec 02 2005 - 02:56:14 CST
[Seacord 20052005a] ] Chapter 6, "Formatted Output"
US-CERT Vulnerability Note [VU#948385]
[Wall 2011] perlfunc

...

01. Input Validation and Data Sanitization    01. Input Validation and Data Sanitization     02. Declarations and Initialization