Tutorial SQL

INICIO SQL Introducción a SQL Sintaxis SQL Seleccionar SQL SQL Seleccionar Distinto SQL donde SQL y, o no Orden SQL por Insertar SQL en Valores nulos de SQL Actualización SQL Eliminar SQL SQL Seleccionar parte superior SQL mínimo y máximo Recuento de SQL, Promedio, Suma SQL como Comodines de SQL SQL en SQL entre Alias ​​SQL Uniones SQL Combinación interna de SQL Unión izquierda de SQL Unión derecha de SQL Unión completa de SQL Unión automática de SQL Unión SQL Grupo SQL por SQL teniendo SQL existe SQL Cualquiera, Todo SQL Seleccionar en Insertar SQL en Seleccionar Caso SQL Funciones nulas de SQL Procedimientos almacenados de SQL Comentarios SQL Operadores SQL

Base de datos SQL

SQL Crear base de datos Base de datos de caída de SQL Base de datos de copia de seguridad de SQL Crear tabla SQL Tabla desplegable de SQL Tabla de modificación de SQL Restricciones SQL SQL no nulo SQL único Clave principal de SQL Clave foránea de SQL Comprobación SQL Valor predeterminado de SQL Índice SQL Incremento automático de SQL Fechas SQL Vistas SQL Inyección SQL Alojamiento SQL Tipos de datos SQL

Referencias SQL

Palabras clave de SQL Funciones MySQL Funciones del servidor SQL Funciones de MS Access Referencia rápida de SQL

Ejemplos SQL

Ejemplos SQL Cuestionario de SQL Ejercicios SQL Certificado SQL

Inyección SQL


Inyección SQL

La inyección SQL es una técnica de inyección de código que podría destruir su base de datos.

La inyección SQL es una de las técnicas de piratería web más comunes.

La inyección SQL es la colocación de código malicioso en declaraciones SQL, a través de la entrada de una página web.


SQL en páginas web

La inyección de SQL generalmente ocurre cuando le pide a un usuario que ingrese, como su nombre de usuario/ID de usuario, y en lugar de un nombre/ID, el usuario le da una instrucción SQL que, sin saberlo , ejecutará en su base de datos.

Mire el siguiente ejemplo que crea una SELECTdeclaración agregando una variable (txtUserId) a una cadena de selección. La variable se obtiene de la entrada del usuario (getRequestString):

Ejemplo

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

El resto de este capítulo describe los peligros potenciales de utilizar la entrada del usuario en sentencias SQL.


La inyección SQL basada en 1 = 1 es siempre verdadera

Mira el ejemplo anterior de nuevo. El propósito original del código era crear una instrucción SQL para seleccionar un usuario, con una identificación de usuario determinada.

Si no hay nada que impida que un usuario ingrese una entrada "incorrecta", el usuario puede ingresar alguna entrada "inteligente" como esta:

ID de usuario:

Entonces, la declaración SQL se verá así:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

El SQL anterior es válido y devolverá TODAS las filas de la tabla "Usuarios", ya que OR 1=1 siempre es VERDADERO.

¿El ejemplo anterior parece peligroso? ¿Qué sucede si la tabla "Usuarios" contiene nombres y contraseñas?

La declaración SQL anterior es muy similar a esto:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Un hacker podría obtener acceso a todos los nombres de usuario y contraseñas en una base de datos simplemente insertando 105 O 1=1 en el campo de entrada.



La inyección SQL basada en ""="" es siempre verdadera

Aquí hay un ejemplo de un inicio de sesión de usuario en un sitio web:

Nombre de usuario:

Contraseña:

Ejemplo

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Resultado

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

Un hacker podría obtener acceso a nombres de usuario y contraseñas en una base de datos simplemente insertando " O ""=" en el cuadro de texto de nombre de usuario o contraseña:

Nombre de usuario:

Contraseña:

El código en el servidor creará una instrucción SQL válida como esta:

Resultado

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

El SQL anterior es válido y devolverá todas las filas de la tabla "Usuarios", ya que OR ""="" siempre es VERDADERO.


Inyección SQL basada en sentencias SQL por lotes 

La mayoría de las bases de datos admiten sentencias SQL por lotes.

Un lote de sentencias SQL es un grupo de dos o más sentencias SQL, separadas por punto y coma.

La declaración SQL a continuación devolverá todas las filas de la tabla "Usuarios", luego eliminará la tabla "Proveedores".

Ejemplo

SELECT * FROM Users; DROP TABLE Suppliers

Mira el siguiente ejemplo:

Ejemplo

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Y la siguiente entrada:

Identificación de usuario:

La instrucción SQL válida se vería así:

Resultado

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

Usar parámetros de SQL para la protección

Para proteger un sitio web de la inyección SQL, puede usar parámetros SQL.

Los parámetros SQL son valores que se agregan a una consulta SQL en el momento de la ejecución, de manera controlada.

Ejemplo de ASP.NET Razor

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Tenga en cuenta que los parámetros se representan en la instrucción SQL mediante un marcador @.

El motor SQL verifica cada parámetro para asegurarse de que sea correcto para su columna y se trate literalmente, y no como parte del SQL que se ejecutará.

Otro ejemplo

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

Ejemplos

Los siguientes ejemplos muestran cómo crear consultas parametrizadas en algunos lenguajes web comunes.

SELECCIONE DECLARACIÓN EN ASP.NET:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();

INSERTAR EN LA DECLARACIÓN EN ASP.NET:

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

INSERTAR EN LA DECLARACIÓN EN PHP:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();