Similar to Python, format string vulnerabilities in programs written in Ruby can allow an attacker to terminate the program prematurely. If Ruby encounters a format specification it does not understand, such as %z, or if the format string contains more specifications than parameters passed to sprintf(), Ruby terminates the program with an error message such as "in 'sprintf': too few arguments. (ArgumentError)" or "in 'sprintf': malformed format string - %z (ArgumentError)". This can let attackers launch denial-of-service attacks or circumvent logging facilities. Ruby does not support %n, so an attacker cannot use format string vulnerabilities to alter variable values.
Format string vulnerabilities are a lesser known type of vulnerability that you should be aware of. C and C++'s support for %n, combined with its lack of stack protection, makes format string vulnerabilities in C and C++ programs particularly exploitable. However, format string vulnerabilities can exist in programs written in other programming languages such as Perl, PHP, Java, Python, and Ruby. Although the consequences of such vulnerabilities may not generally be as high as format string vulnerabilities in C and C++ programs, a resourceful attacker may be able to leverage the vulnerability to launch a denial-of-service attack, discover privileged information, alter variable values, or circumvent logging facilities.
Another risk of including user data in format strings is that a vulnerability in the format string parsing code in the language interpreter or a component library may be exploitable. In December 2005, Jack Louis of Dyad Security discovered a vulnerability in Perl's format string parsing routine (cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-1999-1417). Exploiting this vulnerability required specifying a length exceeding 2,147,483,647, which is unlikely under normal conditions. On the other hand, attackers could easily use a format string vulnerability in Perl programs to specify such a length. Perl programs are not immune to format string vulnerabilities, but the vulnerability in the Perl interpreter increases the potential impact when they do occur. Louis's was not the first discovery of such a vulnerability: In 2000, the PHP interpreter was found to contain a format string vulnerability in its logging facility (cve.mitre.org/cgi-bin/cvename.cgi?name= CVE-2000-0967). Thus, even when a programming language contains protections for format string vulnerabilities, there is still risk in including user input in format strings.
It is important to realize that format string vulnerabilities can have serious security consequences. Avoiding format string vulnerabilities is two-fold:
- Be aware of which routines accept format strings and never include user data in format strings passed to those routines.
- If you want to format the string before outputting it, always use the %s specification and pass the string as an argument.
Thanks to Pamela Curtis for reviewing and editing this article.