¿Ocultar y ocultar las claves de los parámetros de la URL es una protección contra la manipulación?

4

¿El uso de mod_rewrite hace que la inyección de matriz PHP ( manipulación de claves de parámetros web ) sea imposible cuando las claves son desconocidos (y difíciles de adivinar)?

Supongamos que tenemos la siguiente URL:

https://example.com/product.php?id=1&action=show

example.com decidió reescribir las URL a una versión más bonita como:

https://example.com/product/1

Para eso usan el siguiente RewriteRule :

RewriteRule ^/product/(.*)$ /product.php?id=$1&action=show [L]

Ahora las claves son id y action y esos valores son 1 y show . Entiendo que los valores se volverán a escribir, de todos modos no hay protección. Las inyecciones siguen siendo posibles y así sucesivamente. Pero las claves no se pueden cambiar suponiendo que son desconocidas. En este ejemplo, utilicé las claves adivinables id y action , pero también podrían ser dos claves completamente largas y aleatorias.

Ahora mi pregunta es sobre las llaves. Podría inyectar uno o varios [] en el parámetro para hacer que el valor de ese id sea una matriz de PHP en lugar de una cadena. Así:

https://example.com/product.php?id[]=1&action=show

Para una URL reescrita, no es posible hacerlo a menos que conozca la clave. Estoy en lo cierto En este ejemplo, lo siguiente será posible porque la clave es fácil de adivinar. En el siguiente ejemplo, la URL sabrá que tiene la clave id dos veces y usará la última con el [] inyectado.

https://example.com/product/1?id[]=1

Pero suponiendo que las claves no eran conocidas y fáciles de adivinar. Digamos:

RewriteRule ^/product/(.*)$ /product.php?7b8d164d7820713ef5be524d2bde7828999c78d6=$1&28c4abba80b7a2038328e54a81f51367ead9172a=show [L]

Supongo que entonces no hay forma de inyectar [] sin conocer las claves.

Además, cuando verifica la URL actual en su script PHP para los caracteres ? y & , puede evitar omisiones como https://example.com/product/1?id[]=1 . En mi opinión, la inyección de matriz o la modificación de la clave ya no es posible, solo se puede cambiar el valor. ¿Correcto?

    
pregunta Bob Ortiz 14.07.2016 - 11:37
fuente

2 respuestas

2

Ocultará la ubicación real de la secuencia de comandos, pero por sí misma no hay nada que impida que un atacante adivine / dirbustings / etc el archivo product.php y acceda a él directamente. El atacante tendría que identificar los nombres de parámetros correctos (id & action). Una vez que el atacante accede directamente al archivo, la regla de reescritura no se aplica.

Por lo tanto, podría aumentar el esfuerzo mínimo requerido para atacar su secuencia de comandos, sin embargo, es posible que deba volver a escribir las reglas y no sean muy amigables con el rendimiento, por lo que podría estar introduciendo una condición de denegación de servicio en el proceso.

    
respondido por el wireghoul 14.07.2016 - 14:00
fuente
0

Una buena forma de abordarlo es desinfectar las entradas del usuario en un método PHP dedicado poco después de invocar la solicitud.

Esto tiene varias ventajas:

  • Siempre está seguro de que solo se envían los argumentos con el formato correcto, por ejemplo, los ints son ints y las cadenas son cadenas sin nada inusual
  • Se pasa la cantidad correcta de argumentos, por ejemplo, no hay forma de agregar otro argumento y hacer que el script haga otra cosa.

Si puede encontrar dos de los anteriores, es probable que pueda eliminar algunos errores existentes, como pasar una lista incompleta de argumentos y no inicializar correctamente las variables.

Esto le brinda un mejor enfoque estructural para su código PHP y realmente la validación de entrada obligatoria.

La validación de entrada normalmente se realiza mediante métodos estándar, sin embargo, antes de la solicitud de enrutamiento, es bueno tener un lugar donde desinfectarlos: este es un método bueno y válido porque lo importante es desinfectar la entrada antes de llamar a otros métodos.

De esta manera, lo mejor es llamar siempre al método de un controlador, y verificar si todos los argumentos coinciden (existen) y son del tipo requerido (en el método del controlador, que principalmente realiza la comprobación y después de eso solo llama a otro servicio) , por ejemplo (solo es un semi-código para mostrar la lógica en el controlador):

//router
if($_GET['action'] === 'showItem') {
    showItemController();
}

//controller
function showItemController() {
    try {
        $id = $_GET['id'];
        if(!isint($id)) {
           throw new Exception("id '{$id} is wrong");
        }
        $output = showItem($id);
        render($output);
    } catch(Exception $e) {
      logError($e);
      displayGenericFail();
    }
}

//service
function service($id) {
    $item = new Item($id);
    return $item->getHtml();
}
    
respondido por el Aria 11.08.2016 - 17:14
fuente

Lea otras preguntas en las etiquetas