¿Posible SQLi con sentencias preparadas de creación propia y real_escape_string?

2

Mi asignación actual es encontrar una posible inyección de SQL en una aplicación web de PHP. Mientras miraba el código fuente, noté que la forma en que el script maneja las declaraciones preparadas es extraña.

$query = db::prepare("SELECT password FROM vault where id=%s", $_POST['id']);
$res = db::commit($query);

La parte interesante de la función prepare se ve así:

    // escape
    foreach ($args as &$value){
        $value = static::$db->real_escape_string($value);
    }

    // prepare
    $query = str_replace("%s", "'%s'", $query);
    $query = vsprintf($query, $args);
    return $query;

Ahora, buscando formas de evitar esto, noté que las comillas simples se escapan, obviamente debido a la función real_escape_string. Mirando por aquí, encontré la siguiente publicación que indica que establecer% s en comillas simples parece altamente sospechoso . Sin embargo, todavía no he encontrado ninguna forma de explotar esto, o incluso si es explotable.

¿Alguien puede decirme si hay algo incorrecto para escapar y procesar la entrada del usuario de esa manera? Sé que usar las funciones de sentencias preparadas de mysqli / PDO originales es una mejor idea, pero dado que este no es mi código, sería genial averiguar qué es exactamente lo que está mal aquí y por qué no debería hacerlo de esta manera.

    
pregunta Nirusu 20.12.2018 - 16:43
fuente

2 respuestas

0

Podría dar lugar a problemas que no estén directamente relacionados con la seguridad. Debido a que $value debe convertirse a una cadena antes de que real_escape_string() pueda hacer su magia, pueden ocurrir todo tipo de problemas de localización. Piense en , en lugar de puntos decimales o formatos de fecha que no serán aceptados por la base de datos. No es una buena idea manejar todos los parámetros, ya que son cadenas.

    
respondido por el martinstoeckli 20.12.2018 - 18:21
fuente
0
  

si hay algo incorrecto para escapar y procesar la entrada del usuario de esa manera?

Para aclarar, no hay nada de malo en escapar de per se siempre y cuando se use a propósito, para escapar no de la "entrada de usuario" arbitraria, sino específicamente de los datos que se utilizarán en los literales de cadena en Consulta SQL Francamente, siempre que los datos en la consulta SQL se citan y se escapen, no debería haber ningún daño posible.

El código en cuestión es un caso especial. Aunque se utiliza el escape masivo (que es una gran bandera roja como regla general), en este caso debe considerarse seguro siempre que solo se utilicen marcadores de posición de printf básicos (es decir, %s, %d, %f etc), sin intercambio de argumentos y otras cosas extravagantes. Como resultado, cada variable de entrada sería cualquiera

  • envuelto en comillas si se usa el marcador de posición %s (y, por lo tanto, se cotiza y se escapa para satisfacer la regla de lo anterior);
  • o se formatea como un número en caso de que se use cualquier otro marcador de posición.

Por lo tanto, no veo ninguna posibilidad de inyección.

El único pequeño problema de seguridad aquí es utilizar mysqli :: set_charset () para configurar la codificación de la conexión, para evitar una vulnerabilidad virtual cuando se utiliza una codificación obsoleta peculiar.

    
respondido por el Your Common Sense 20.12.2018 - 17:46
fuente

Lea otras preguntas en las etiquetas