PHP: Uso adecuado de parse_str
Por: alex | 26 Junio 2007 | Ver comentarios |
La siguiente porción de código es una práctica muy extendida en WordPress, sirve para que las funciones puedan tener un buen número de parámetros opcionales sin que el código sea visualmente feo:
<?php
/* Funciones de WordPress */
function stripslashes_deep($value) {
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
function wp_parse_str( $string, &$array ) {
parse_str( $string, $array );
if ( get_magic_quotes_gpc() )
$array = stripslashes_deep( $array );
return $array;
}
/* Fin */
function get_posts( $args = '' ) {
$defaults = array(
'limit' => 5,
'post_type' => ''
);
$args = wp_parse_str($args, $defaults);
extract($args, EXTR_SKIP);
$where = '';
if ( !empty($post_type) )
$where = "WHERE post_type = '$post_type'";
$sql = "SELECT * FROM posts $where LIMIT $limit";
// ejecutar la consulta en una base de datos MySQL
echo htmlspecialchars($sql);
}
$limit = empty($_GET['limit']) ? 5 : (int) $_GET['limit'];
if (get_magic_quotes_gpc())
$_GET['type'] = stripslashes($_GET['type']);
// Se usa addslashes sólo para el ejemplo.
// $type = mysql_real_escape_string($_GET['type']);
$type = addslashes($_GET['type']);
get_posts("limit=$limit&post_type=$type");
?>Sobre el ejemplo mostrado:
- ¿Tiene algún problema de seguridad?
- ¿Qué pasa si cambiamos la línea resaltada por esta otra, tiene algún problema de seguridad?
$where = "WHERE post_type = '". addslashes($post_type) . "'";
Para los interesados en este pequeño quiz, subí una página en la que pueden realizar sus pruebas.


Jaime
27 de Junio de 2007, 04:17:00 pm
¿No hay un sql injection muy gordo?
alex
27 de Junio de 2007, 04:26:14 pm
Si, pero ¿con qué valores se produce ese fallo?
Jaime, Sirw2P
27 de Junio de 2007, 04:49:19 pm
Aps… deja que sigo tocando y trasteando, no se con que valores entran…
g30rg3_x
27 de Junio de 2007, 10:28:32 pm
Con cualquier doble codificacion pasas los filtros…
%2527 = %27 = ‘
Saludos alex..
alex
27 de Junio de 2007, 10:36:40 pm
Tienes razón g30rg3_x, ¿qué pasa en el segundo caso?
Saludos
g30rg3_x
27 de Junio de 2007, 11:53:17 pm
LOL, se me olvido responder esa…
Bueno desde mi punto de vista no hay amenaza (o no le veo ninguna) fuera de la que requiere un escenario especial que ya hemos discutido tiempo atras (si es que no mal recuerdo) y que se refiere a unos problemitas de mysql y algunas codificaciones:
http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
Saludos
jdeveloper
28 de Junio de 2007, 12:29:48 pm
Hola, alguien me puede explicar de que codificacion se trata %2527 = %27 = ‘, pensaba que era utf pero no lo creo. Me gustaria saber el por que de la doble codificación. El enlace que puso g30rg3_x no me servio de mucho, quiza algo en castellano?
Saludos y gracias de antemano
alex
28 de Junio de 2007, 12:47:17 pm
@g30rg3_x: Todavía queda otro problema de SQL Injection
@jdeveloper: Simplemente está codificando el apóstrofe dos veces.
<?php echo urlencode(urlencode('\'')); ?>Se hace esto para que la función
addslashesno tenga ningún efecto sobre el valor de$_GET['type']="algo%27", este último se convierte en$post_type="algo'"gracias a la acción de parse_str.Puedes ver un ejemplo en la página de prueba.
Saludos
paco
28 de Junio de 2007, 03:06:25 pm
yo no veo nada, podrías echarnos una manita? :S
alex
28 de Junio de 2007, 11:54:57 pm
El segundo error tiene que ver en parte con
parse_stry el tratamiento de arrays.jdeveloper
29 de Junio de 2007, 03:08:35 am
gracias alex, en cuanto tenga tiempo lo mirare mas detenidamente, pero ya voy pillando la dinamica a seguir.
g30rg3_x
29 de Junio de 2007, 07:07:38 pm
Bueno sigo sin ver lo que creo que estas pidiendo..
Pero mirando con mas detenimiento veo un medio-SQL-injection en $limit, ya que parse_str nos permite sobreescribir variables locales (http://www.acid-root.new.fr/advisories/14070612.txt) podriamos llamar a algo asi…
?limit=2&type=foo%26limit=bar
Asi basicamente estamos pasando el filtro de solo numeros (o mejor dicho el casting a integer) que hay un poco mas arriba, aunque claro no obtendremos nada beneficioso ya que nos encontramos de tras de un LIMIT pero talvez nos podria servir para sacar informacion.
Aunque como te dije aun no le veo por donde intente meter arrays durante pero ninguna de mis pruebas me dio positivo, asi que yo tambien quedo al pendiente de la solucion de la segunda parte…
Saludos alex…
alex
29 de Junio de 2007, 08:07:22 pm
g30rg3_x, justamente me refería a ese problema, puesto que con valores parecidos (
?limit=2&type=foo%26limit=1%20UNION%20ALL%20...) al que mencionas, se sobreescribe el valor de la variablelimithaciendo posible la inyección de SQL.Eso es correcto siempre y cuando se haga uso de
ORDER BYen la consulta, pero como en el ejemplo no existe esa parte se puede construir sentencias SQL perfectamente válidas.En el comentario anterior hacía referencia a arrays, porque básicamente al ser éstas tablas hash, la última asignación a una misma llave (
limit) es la que cuenta.Saludos
g30rg3_x
29 de Junio de 2007, 08:17:57 pm
jejejejeje..
Se me fue me concentre tanto en post_type que no le di importancia, si perdon error mio lapsus brutus de conocimiento de sql…
Saludos