PHP sprintf considered harmful?
I learned about Format String Attacks a few years ago on the hard way. Now I recently saw some PHP code:
<?php
echo sprintf($_GET['format'], $_GET['value1'], $_GET['value2']);
I tried running it like this with $_GET['format']
set to type strings %s%s%s...
, but PHP only exists with PHP Warning: sprintf(): Too few arguments in file.php on line 2
. Isn't it still possible to do a formatted string attack?
source to share
I also found integer overflow. Which leads to this:
<?php
echo sprintf('%2147483646$s', "foo"); # Warning: Too few arguments
echo sprintf('%2147483647$s', "foo"); # Warning: Argument number must be greater than zero
I filed this as PHP Bug # 61531 . I'm not sure if it can be used.
source to share
Not sure if there is a PHP sprintf () vulnerability, but the sample code seems like a prime example of how not to do something.
As far as I know, sprintf should help you lock the line, not the other way around. For example, this is what I find to be a useful reason for using sprintf ():
$sql = sprintf(
"insert into table (myname, myvalue) values ('%s', '%s')",
mysql_real_escape_string( $_GET['name'] ),
intval( $_GET['value'] )
);
A more useful reason for using sprintf is to borrow its cousin, vsprintf, and constantly reuse it:
// takes variable number of parameters
function sanitize() {
$args = func_get_args();
$sql = array_shift( $args );
foreach( $args as $k => $v ) $args[$k] = mysql_escape_string( $v );
$safe_sql = vsprintf( $sql, $args );
return( $safe_sql );
}
With it, you can safely isolate parameters from requests and assume they will be sanitized:
$t = mysql_query(sanitize(
"insert into mytable (myname, myvalue) values ('%s', '%s')",
$_GET['name'],
$_GET['value']
));
source to share