PHP obtiene vulnerabilidad de código de parámetro [cerrado]

-2

Tengo una URL como esta:

mywebsite.com?id=12345678

Recupero id y lo paso a un function como este:

$id = $_GET["id"];
if(isset($id)){
  dosomething($id);
}

Soy nuevo en PHP y realmente no entiendo si de alguna manera el $id param podría ser explotado para ejecutar algún código. Lo veo solo como una cadena.

    
pregunta steo 03.01.2018 - 12:19
fuente

3 respuestas

2

Depende completamente de lo que dosomething haga.

Uno de los muchos posibles ataques es la inyección de sql si no desinfecta los parámetros que se pasan a sql y no usa declaraciones preparadas.

Por ejemplo, si dosomething() hace algo en la línea de: sql.query("SELECT * FROM users WHERE userid=$id") sin verificar primero la validez de $id , simplemente podría visitar su sitio web con: ID 1 OR id!=1 . Dependiendo de lo que haga con el resultado, es posible que haya expuesto su tabla de usuarios completa. O podría ser desagradable y simplemente hacer: ID = 1; DROP TABLE users .

Entonces, sí: debe validar todas las aportaciones del usuario y del cliente antes de hacer algo con él.

    
respondido por el Marc 03.01.2018 - 12:25
fuente
0

Esto depende de lo que something() está haciendo. En general, no desea que los usuarios puedan pasar datos arbitrarios a sus scripts. Tu código hace esto, ya que no verificas, si la entrada del usuario es la que esperabas que fuera.

Diciendo esto de manera abstracta: ¡Nunca hagas suposiciones sobre lo que obtienes!

Ejemplo: Genera una consulta SQL como esta:

if(isset($_GET["id"])) {
    $sql = "SELECT * FROM table WHERE id = ".$_GET["id"].";"
    // execute SQL here
    // process results here
}

Supongamos que obtiene esta entrada de un formulario, que establece que el campo "id" solo debe rellenarse con un número (o incluso usar el atributo HTML5).

Usuario inconsciente

Este tipo inserta un valor no numérico, como ab"fe; y envía el formulario. Su solicitud generará un error / excepción de SQL, ya que la consulta resultante es:

SELECT * FROM table WHERE id = "ab"fe;"; SQL inválido

Esto sucedió porque asumiste que solo obtendrías valores numéricos, pero nada impide que un usuario envíe otra cosa. Incluso si utiliza el atributo HTML5, un navegador de usuarios puede ignorarlo o el propio usuario crea una solicitud específica y la envía a su punto final. Veamos un escenario peor.

Usuario malintencionado

Este chico intenta meterse contigo y envía owned"; DROP DATABASE * donde la declaración SQL resultante es:

SELECT * FROM table WHERE id = "owned"; DROP DATABASE *; poof, tu base de datos se ha ido ...

En general, siempre desea estar absolutamente seguro de que sabe qué tipo de datos está procesando. Use métodos como is_numeric() para asegurarse de que los datos contengan lo que usted cree que hace. Este proceso de eliminar datos no deseados y prepararlos para su uso se denomina desinfección .

Además, siempre debe cadenas de escape antes de usarlas en una declaración SQL, para evitar que alguien inyecte caracteres especiales, como "" o ; en SQL.

Mala o la falta completa de desinfección de datos es una gran vulnerabilidad, así que tenga cuidado, siempre que use algo que un usuario le envíe. Verifique todo el lado del servidor, no confíe en los formularios de JavaScript que deshabilitan el botón "Enviar", ya que las personas aún pueden enviar solicitudes creadas a su servidor.

    
respondido por el GxTruth 03.01.2018 - 14:36
fuente
0

Al contrario de la mayoría de las respuestas aquí, para mí la necesidad no depende de lo que dosomething() hace. Aplicando la defensa en profundidad, mi línea de defensa es siempre desinfectar el valor que llega desde fuera del entorno antes de hacer cualquier otra cosa con él. Tal vez sea una exageración, pero es mejor probar un poco más para obtener más seguridad a costa del pequeño rendimiento, que probablemente sea insignificante de todos modos, en lugar de lo contrario.

Entonces, dosomething() tiene una API y dado que su idioma no lo hace por defecto con el tipo y la validación de contenido, verificaría la variable $id antes de inyectarla en dosomething() . Basado en su API, usted sabe que $id debería ser algo específico, como un entero, una cadena, o lo que sea. Así que haga una prueba para eso, incluyendo su longitud según sea necesario, y cancele prematuramente y antes de llamar a doSomething() es que las cosas no son lo que esperaba.

La única otra opción sería hacer las mismas pruebas que las primeras líneas dentro de dosomething() . Pero esto depende si controlas ese pedazo de código o no. Por ejemplo, si estuvieras usando algunas bibliotecas, la primera ruta de acción (para probar antes de llamarlo) sería mejor, porque incluso si la biblioteca prueba cosas, hacerlo tú mismo también debería cubrir más casos y crear menos debilidades.

    
respondido por el Patrick Mevzek 03.01.2018 - 15:40
fuente

Lea otras preguntas en las etiquetas