it-swarm-es.com

¿Mejores prácticas para prevenir la inyección de SQL?

La inyección de SQL es siempre un tema candente, especialmente cuando se trata de seguridad web. En este sentido, estoy interesado en cuáles son los pasos que siempre se deben tomar para evitar la inyección de SQL en cualquier aplicación web. Además de estos pasos normales, ¿hay algo más que la gente haga más allá de lo normal para evitarlo?

17
Mark Davidson

Ya hay muy buenas respuestas a esta pregunta, sin embargo, me gustaría mencionar algunas más:

  • Codificación segura (que ya ha sido mencionada por muchos)
    • Escapar de la entrada del usuario
    • Consultas parametrizadas (sentencias preparadas, consultas predefinidas donde solo se vinculan variables)
    • Código defensivo
  • Monitoreo de ataques
    • Sistema de detección de intrusiones en red (NIDS)
    • Sistema de detección de intrusiones del huésped (HIDS)
    • Sistema de detección de intrusiones de aplicaciones (AppIDS)
  • Bloquear ataques
    • Firewall de aplicaciones
    • Cortafuegos de base de datos
    • Cortafuegos de aplicaciones web
      • Apache ModSecurity
      • Sistema de velocidad de aplicaciones de Cisco (AVS)
  • Sondeo de vulnerabilidades
    • Prueba automatizada de inyección de blackbox
    • Análisis de código fuente estático
    • Prueba de penetración manual

Esto es solo para prevención y no he tenido en cuenta endurecimiento del servidor sql. Sin embargo, hay muchas similitudes.

Las defensas adicionales en caso de que ya sea vulnerable a la inyección serían:

  • Ejecutando su aplicación con la menor cantidad de subvenciones necesarias
    • Específicamente otorgue solo acceso a la base de datos y tablas que necesita
    • Asegúrese de otorgar solo el privilegio que necesita (generalmente seleccionar, insertar, actualizar)
19
Chris Dale

Declaraciones preparadas, consultas parametrizadas, escapar de todas las entradas del usuario, para un buen comienzo, consulte http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet .

16
Weber

La defensa clave es usar solo API que escapen de forma segura a las consultas de la base de datos; generalmente, se denominan declaraciones parametrizadas o preparadas. No se pueden usar en todos los casos (por ejemplo, cuando se proporciona un identificador de SQL como el nombre de la tabla o columna en tiempo de ejecución), pero es el mejor enfoque donde sea posible (la mayoría de los casos).

Nota: esto puede llevar a que se ingresen datos dañinos en la base de datos, así que tenga en cuenta eso cuando use estos datos en otra parte de la aplicación

La segunda defensa es adoptar un enfoque de escape. Este es el enfoque de "reemplazar una cita simple con dos citas". Si necesita seguir este camino, debe escapar de cada carácter potencialmente dañino, lo que significa más que comillas simples en algunos casos. Aconsejaría usar una biblioteca de nivel superior, como OWASP ESAPI, si es posible para que lo haga por usted, o lea detenidamente la Hoja de trucos de inyección SQL de OWASP (mencionada anteriormente).

10
Justin Clarke

El paso principal para proteger la aplicación web contra la inyección de SQL es desinfectar adecuadamente cualquier entrada del usuario (especialmente la entrada utilizada en consultas SQL). En algunos lenguajes/marcos, existen formas estándar de cómo manejar estos valores, por ejemplo, usando consultas parametrizadas en lugar de componer la consulta uniendo valores de cadena.

9
bretik

Estoy enseñando seguridad informática en politécnicos. A menudo, los estudiantes tienen cierta confusión sobre los términos utilizados para la inyección de SQL, así que permítanme tratar de aclararlos.

En el contexto de una aplicación web como Facebook,

La inyección SQL es cuando el usuario web normal ingresa el código SQL en los campos de datos.

 ' OR '1'='1 into the textboxes of a login form.

La mejor persona para evitar la inyección de SQL es el desarrollador web, también conocido como la persona encargada de escribir código para que la aplicación web lea/escriba datos en la base de datos.

La forma más fácil de evitar la inyección de SQL por parte del desarrollador web es utilizar consultas parametrizadas.

Las declaraciones preparadas y las consultas parametrizadas significan lo mismo.

Usaré consultas parametrizadas desde este punto en adelante.

Las consultas parametrizadas se refieren a la forma en que primero se define el código SQL y luego los datos se colocan dentro de los parámetros apropiados.

Por ejemplo, en .Net

Update `users` set `name` = @name where `id` = @id

los parámetros @name y @id son los datos. El resto son el código SQL.

Tenga en cuenta que las consultas parametrizadas son ¡generalmente pero no siempre realizadas en el código de la aplicación web.

Hay 2 formas comunes de escribir consultas parametrizadas.

  1. En el código de la aplicación web según el idioma utilizado
  2. En la base de datos usando procedimientos almacenados

Entonces, en cierto sentido, sí, los procedimientos almacenados son una forma de consultas parametrizadas.

Hay otras formas de evitar la inyección de SQL que es escapar de caracteres especiales como comillas simples. Por ejemplo, en PHP, puede usar mysql_real_escape_string que básicamente solo pone barras antes de las comillas simples.

Esto no es ideal debido a problemas con% y subrayado para el operador LIKE en ciertas bases de datos como MySQL. ver este pdf para más detalles.

Para resumir, todas las opciones sugeridas tienen que ver con desinfectar (limpiar) la entrada del usuario para limpiar el código SQL.

La mejor manera es usar consultas parametrizadas dependiendo del lenguaje de programación utilizado.

Fin de la historia.

4
Kim Stacks

Desde el punto de vista del desarrollador web, se debe señalar lo que Weber ya ha mencionado.

Además, se puede configurar el firewall de la base de datos, como GreenSQL: http://www.greensql.net/ . Funciona como un proxy entre su aplicación y la entrada del usuario, vigila lo que debe pasar y etc. Sin embargo, esto conlleva un mayor tiempo de respuesta.

4
anonymous

Use API de acceso a datos decentes que faciliten hacer lo correcto de manera segura.

Aquí está ActiveRecord v3:

# basic usage
@user = User.where(:username => '[email protected]').first

# with a SQL-string fragment, but using parameters
@projects = @user.projects.where('status = ?', params[:status])
3
yfeldblum