¿Qué es la inyección SQL?

Posibles duplicados:

¿Cómo funciona la inyección SQL del cómic XKCD “Bobby Tables”?
https://stackoverflow.com/search?q=sql+injection

¿Alguien puede explicar la inyección SQL? ¿Cómo causa vulnerabilidades? ¿Dónde exactamente está el punto donde se inyecta SQL?

¿Alguien puede explicar SQL Injecton?

La inyección de SQL ocurre cuando usted interpola un poco de contenido en una cadena de consulta SQL, y el resultado modifica la syntax de su consulta de formas que no pretendía.

No tiene que ser malicioso, puede ser un accidente. Pero es más probable que la inyección accidental de SQL genere un error que una vulnerabilidad.

El contenido dañino no tiene que provenir de un usuario, podría ser contenido que su aplicación obtenga de cualquier fuente, o incluso generarse en código.

¿Cómo causa vulnerabilidades?

Puede provocar vulnerabilidades porque los atacantes pueden enviar valores a una aplicación que saben que se interpolará en una cadena SQL. Al ser muy inteligentes, pueden manipular el resultado de las consultas, leer datos o incluso cambiar los datos que no se les debe permitir.

Ejemplo en PHP:

$password = $_POST['password']; $id = $_POST['id']; $sql = "UPDATE Accounts SET PASSWORD = '$password' WHERE account_id = $id"; 

Supongamos ahora que el atacante establece los parámetros de la solicitud POST en ” password=xyzzy ” e ” id=account_id “, lo que da como resultado el siguiente SQL:

 UPDATE Accounts SET PASSWORD = 'xyzzy' WHERE account_id = account_id 

Aunque esperaba que $id fuera un número entero, el atacante eligió una cadena que es el nombre de la columna. Por supuesto, ahora la condición es verdadera en cada fila, por lo que el atacante acaba de establecer la contraseña para cada cuenta. Ahora el atacante puede iniciar sesión en la cuenta de cualquier persona, incluidos los usuarios con privilegios.

¿Dónde exactamente está el punto donde se inyecta SQL?

No es SQL lo que se inyecta, es contenido que se interpola (“inyecta”) en una cadena SQL, lo que da como resultado un tipo diferente de consulta de la que yo pretendía. Confié en el contenido dynamic sin verificarlo, y ejecuté la consulta SQL resultante a ciegas. Ahí es donde comienza el problema.

La inyección de SQL es un error en el código de la aplicación, generalmente no en la base de datos o en la biblioteca o el marco de acceso a la base de datos.

La mayoría de los casos de inyección SQL pueden evitarse mediante el uso de parámetros de consulta. Consulte ¿Cómo puedo evitar la inyección de SQL en PHP? por ejemplo.

La inyección SQL ocurre cuando el usuario de una aplicación puede afectar el significado de la consulta de la base de datos. Esto ocurre a menudo cuando las cadenas arbitrarias de la entrada del usuario se concatenan para crear SQL que se alimenta a la base de datos. Por ejemplo, digamos que tenemos el siguiente código (en PHP, pero lo mismo vale para cualquier idioma), que podría usarse para manejar un inicio de sesión de usuario.

 $sql = "SELECT FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'"; 

El daño se hace cuando el usuario ingresa algo así como

 administrator'; -- 

… para el nombre de usuario. Sin la encoding adecuada, la consulta se convierte en:

 SELECT * FROM users WHERE username='administrator'; -- AND password='' 

El problema aquí es que ‘en el nombre de usuario cierra el campo de nombre de usuario y luego el – inicia un comentario SQL haciendo que el servidor de la base de datos ignore el rest de la cadena. El resultado neto es que el usuario ahora puede iniciar sesión como administrador sin tener que conocer la contraseña. SQL Inection también se puede utilizar para ejecutar consultas ACTUALIZAR, ELIMINAR o ABANDONAR y realmente dañar la base de datos.

La inyección de SQL se puede prevenir mediante consultas parametrizadas o aplicando las funciones de escape de su idioma / herramienta (como mysql_real_escape_string () en PHP).

Una vez que comprenda la Inyección de SQL obtendrá la broma detrás de esta caricatura .

La inyección SQL ocurre cuando las cosas que se supone que son datos se tratan como código SQL de mala gana.

Por ejemplo, si tuviera que hacer

 mysql_query("SELECT * FROM posts WHERE postid=$postid"); 

Normalmente obtendrá la publicación con una identificación dada, pero suponga que $postid está configurado en la cadena 10; DROP TABLE posts -- 10; DROP TABLE posts -- ; De repente, la consulta real que está enviando es

 mysql_query("SELECT * FROM posts WHERE postid=10; DROP TABLE posts --"); 

Esto es un gran problema, ya que estarías perdiendo toda la tabla de mensajes debido a un usuario malicioso, ¡cariño!

La manera más fácil de evitar esto es usar declaraciones preparadas, por ejemplo a través de PDO o MySQLi .

El ejemplo equivalente en PDO sería entonces

 $statement = $db->prepare('SELECT * FROM posts WHERE postid = :postid'); $statement->bindValue(':postid', $postid); $statement->execute(); 

Al hacerlo, se asegura de que el sistema de la base de datos sepa que $ postid se debe tratar como datos y no como código, y por lo tanto se manejará de manera adecuada.

Esta pregunta ha sido respondida muchas veces en StackOverflow, pero es un tema importante que todos deben conocer, así que no voy a votar para cerrar esta pregunta.

Aquí hay enlaces a algunas de mis respuestas anteriores sobre este tema:

  • ¿Qué es la inyección SQL?
  • ¿Cómo protejo esta función de la inyección de SQL?
  • ¿Son los parámetros realmente suficientes para prevenir las inyecciones de Sql?
  • ¿La inyección SQL es un riesgo hoy en día?

También di una presentación en la Conferencia MySQL este mes, y mis diapositivas están en línea:

  • Mitos y falacias de inyección de SQL

La inyección SQL es donde un usuario malintencionado colocará SQL en los campos de entrada para probar y ejecutar el SQL en su servidor.

El consejo n. ° 1 al que me adhiero es usar procedimientos almacenados parametrizados en lugar de crear código SQL sin procesar.

Los parámetros del Procedimiento almacenado no se ejecutan, lo que los hace seguros en la mayoría de los casos.

Encontré que este artículo es una muy buena lectura sobre las técnicas de inyección SQL (enlace a PDF): Inyección SQL avanzada en aplicaciones de SQL Server .

A pesar de que el título dice “Avanzado”, es bastante legible, incluso si no tiene mucho conocimiento sobre la inyección SQL.

Para obtener antecedentes generales, consulte el artículo de Wikipedia sobre Inyección SQL .

En resumen, los ataques de inyección SQL pueden dejarlo vulnerable a todos los daños o robos de datos de la base de datos. Los detalles exactos de lo que se puede hacer a su sistema dependen de los detalles del sistema en sí.

Cada vez que pasa información de sus usuarios a su base de datos, tiene un posible punto de inyección. A este respecto, a menudo faltan aplicaciones web, ya que los nuevos progtwigdores a menudo no comprenden los riesgos de manejar las entradas de los usuarios, y las aplicaciones web son atacadas por personas muy inteligentes que nunca pensaron que encontrarían en su progtwig.

Le gustará este artículo del proyecto de código; )

Resumen

  • Cifrar datos confidenciales.
  • Acceda a la base de datos usando una cuenta con los menos privilegios necesarios.
  • Instale la base de datos usando una cuenta con los menos privilegios necesarios.
  • Asegúrese de que los datos sean válidos.
  • Haga una revisión del código para verificar la posibilidad de ataques de segundo orden.
  • Use consultas parametrizadas.
  • Usa procedimientos almacenados.
  • Vuelva a validar los datos en procedimientos almacenados.
  • Asegúrese de que los mensajes de error no revelen nada sobre la architecture interna de la aplicación o la base de datos.

El punto donde se inyecta SQL es cualquier punto en el que su aplicación acepte la entrada del usuario.

Si esto se convierte en una vulnerabilidad peligrosa para su aplicación web depende de si esta entrada se usa posteriormente como parte de una consulta SQL sin verificar adecuadamente su tipo y escapándolo si es necesario.

Sin un escape adecuado, el motor de SQL podría ejecutar algún código SQL ‘inyectado’ como código SQL, en lugar de un simple string o valor.