The Perl programming language is commonly used for web applications, among others. Perl provides stack checking and other security features that make many types of vulnerabilities that are common to C programs simply not possible. Moreover, Perl provides a taint mode that marks data from untrusted sources as tainted. Some operations, such as running system commands, are not allowed on data marked as tainted. While this prevents compromise, the Perl interpreter's behavior in such cases is to exit with an error message. These protections do not, however, eliminate the possibility or risk of a format string vulnerability in Perl.
In April 2005, Stefan Schmidt reported a problem in postgrey that was a result of a format string vulnerability (cve.mitre.org/ cgi-bin/cvename.cgi?name=CVE-2005-1127). Postgrey is an anti-SPAM program that works with Postfix to implement greylisting. Stefan Schmidt was having problems with postgrey crashing on e-mail from similar e-mail addresses. These e-mail addresses were of the form foo_bar%nowhere.com.xy@[622.622.615.619]. The problem with this e-mail address is that, if a Perl program uses it in a format string, Perl interprets the %n in the format string and writes the number of characters written thus far to the memory location specified on the stack. In the case of postgrey, no other value was placed on the stack, causing the crashes.
The Perl interpreter partially protects the stack in sprintf() by using a special item that is marked as unwritable. The interpreter can detect when a Perl program specifies %n but does not pass an appropriate parameter. The result is that the program exits with a message such as "Modification of a read-only value attempted at foo.pl line 345." This causes the program to crash but does not allow the vulnerability to be exploited by attackers to execute arbitrary code by altering the stack.
Another, more serious consequence of format string vulnerabilities in Perl is illustrated by the following code example. It comes from a paper on Perl format string vulnerabilities by Steve Christey of MITRE (www.securityfocus.com/archive/1/418460/30/0/threaded), a draft of which was written in 2002.
$a = "A"; printf ("Before: $a\n"); printf ("$ARGV", $a); printf ("After: $a\n");
If this script is called vulcode, then ./vulcode %n prints:
Before: A After: 0
In fact, users could set $a to be any nonnegative integer value. The consequence of this flaw depends on how $a is later used. It may not be a vulnerability at all or it may allow attackers to subvert the program.
Format string vulnerabilities in PHP are difficult to directly exploit. PHP does not support %n. If the number of specifications exceeds the number of parameters, the script outputs a message of the form:
Warning: sprintf(): Too few arguments in foo.php on line 4
PHP does not halt executions due to this error message, so the script continues to execute. However, the string constructed by the sprintf() call is blank, which may result in blank log messages or other problems, such as an attacker being able to eliminate a message via cross-site scripting.