Evasión de inyección SQL

0

Sé que filtrar una mala palabra clave no es un buen método para prevenir la inyección de SQL. Sin embargo, cuando no pude responder por qué este no es un buen enfoque, aquí está mi regla:

1) Cuando veo ; , lo hago a '' (para que nadie pueda hacer otra línea de declaración SQL).

2) cuando veo ' , lo hago a '' . (Creo que esto debería evitar la fuga de citas).

3) Cuando veo * , lo hago a &#42 (para que el pirata informático no obtenga la información de mi mesa).

4) Cuando veo -- , lo hago a - (para evitar que el pirata informático intente comentar mi declaración).

^ La razón por la que invento estas 4 reglas se debe a una guía SQLi que se encuentra en aquí

Digamos que hago lo siguiente en mi servidor cuando analizo una declaración SQL: db.exc("INSERT INTO name VALUES ('{}', '{}');".format(firsname, lastname))

Y cuando veo la regla que establezco, creo que es técnicamente seguro prevenir la inyección de SQL en esta declaración. ¿Estoy en lo correcto? Si no puede proporcionar una manera de romperlo? (Conozco las mejores prácticas, pero no puedo entender por qué no lo es). ¿Puede alguien ayudarme con un ejemplo?

    
pregunta Alex 14.04.2018 - 23:58
fuente

2 respuestas

3

Una forma obvia de romper esto: ataques utilizando cosas que no son cadenas (por ejemplo, números) donde se supone que el usuario ingresa algo como 45 (que se manipula en el código como una cadena porque sale de algo de HTML de esa manera, pero no está delimitado por apóstrofes en el SQL porque es un campo de tipo numérico), sino que puede ingresar una subconsulta SQL completa (o una llamada a un procedimiento, o al menos algunas cláusulas adicionales ...).

Tampoco estás cerca de los meta-personajes para captarlos. Por ejemplo, usar -- para iniciar un comentario no es la única manera (no estoy seguro de si está en el estándar general de SQL); Otra forma de iniciar un comentario de una sola línea (que también admite MySQL) es # , y no estás haciendo nada al respecto. Consulte enlace

Otros problemas: supongamos que suponemos que logró hacer esto "completamente" de alguna manera. Luego, en algún momento en el futuro, cambia los motores de base de datos (o simplemente actualiza a una nueva versión) y el nuevo servidor de base de datos admite algunos meta-caracteres nuevos (como un inicio de un comentario, como un final de línea, como un fin de cadena, como un delimitador de subconsultas, como algo completamente distinto ...), y de repente su "solución" vuelve a ser vulnerable.

Deja de intentar reinventar la rueda. Existen declaraciones preparadas / consultas parametrizadas para todos los controladores de base de datos. Algunos motores de base de datos admiten procedimientos almacenados definidos por el usuario, que no solo están parametrizados sino que también se ejecutan más rápido que las cadenas SQL normales.

Si absolutamente debe combinar la entrada del usuario con el SQL sin procesar por alguna razón (esto es raro y, por lo general, puede evitarse siendo más inteligente con su código, pero en algunos lugares puede hacerlo » t simplemente use consultas parametrizadas), use una función de biblioteca bien probada para ello. Básicamente, estás intentando volver a implementar mysql_escape_string , y el primer intento también salió mal .

    
respondido por el CBHacking 15.04.2018 - 01:22
fuente
0

Sus métodos de filtrado no son muy útiles, debería usar métodos de seguridad incorporados en lugar de reemplazar los caracteres usted mismo.

Supongo que puedes hacer ambas cosas, pero recuerda que mysqli_query () no acepta automáticamente varias declaraciones SQL, por lo que eso soluciona tu primer problema.

mysql_escape_string() corrige su segundo problema, y también debería solucionar una serie de otros problemas con valores que se interpretan como de mayor importancia de la que deberían.

Lo que actualmente tiene en su lugar se conoce como lista negra, no es completamente efectivo a menos que se use en combinación con otros métodos de mitigación de Inyección de SQL. Recomiendo usar una lista blanca si es posible. Entonces, por ejemplo, solo aceptarías enteros como entrada.

La lista negra es así:

  

Acepto todo excepto por ...

La lista blanca es así:

  

No lo permito todo excepto por ...

Por lo tanto, cuando se usan correctamente, las listas blancas son mucho más efectivas que una lista negra. Recuerde que las inyecciones de SQL son muy, muy avanzadas y han existido durante mucho tiempo. Todo lo que tiene es una lista negra de 4 reglas, si era tan simple evitar todos los ataques de inyección de SQL con una lista negra que contiene solo 4 reglas, entonces SQLi no sería un problema.

    
respondido por el Cillian Collins 11.05.2018 - 15:02
fuente

Lea otras preguntas en las etiquetas