Gilberto 🦁 PRO
Desarrollo visualizaciones y aplicaciones en línea, colaboro con distintos medios digitales
Sin importar el lenguaje que elijan, el procedimiento general de interacción con una base de datos es básicamente el mismo
Interfaz
Aplicación
Base de datos
¿Qué tanto podemos confiar en la información que proviene desde la interfaz?
$query = "SELECT nombre, apellido, saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '" + $_POST['username'] + "'
AND password ='" + $_POST['password'] + "'";
String query = "SELECT nombre, apellido, saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '" + request.getParameter("username") + "'
AND password ='" + request.getParameter("password") + "'";
PHP
Java
SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = 'USERNAME'
AND password ='PASSWORD';
MySQL
¿Qué tanto podemos confiar en la información que proviene desde la interfaz?
$query = "SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '" + $_POST['username'] + "'
AND usuario.password ='" + $_POST['password'] + "'";
String query = "SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '" + request.getParameter("username") + "'
AND usuario.password ='" + request.getParameter("password") + "'";
PHP
Java
SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '200239644'
AND usuario.password ='#$$%$%&123';
MySQL
¿Qué tanto podemos confiar en la información que proviene desde la interfaz?
$query = "SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '" + $_POST['username'] + "'
AND usuario.password ='" + $_POST['password'] + "'";
String query = "SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '" + request.getParameter("username") + "'
AND usuario.password ='" + request.getParameter("password") + "'";
PHP
Java
SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '1' OR '1' = '1'
AND usuario.password ='1' OR '1' = '1';
MySQL
usuario:
1' or '1' = '1
password:
1' or '1' = '1
La consulta resultante regresa un usuario registrado porque la cláusula 1 = 1 es siempre verdadera
SELECT usuario.nombre, usuario.apellido, cuenta.saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = '1' OR '1' = '1'
AND usuario.password ='1' OR '1' = '1';
MySQL
A este tipo de vulnerabilidades se le conoce como inyección de SQL porque, literalmente, trata de inyectar código para hacer que una consulta se cumpla sin importar su origen
Hay muchas (pero muchas) soluciones distintas para lidiar con el problema de inyección desde diversos lenguajes de programación:
Hay muchas (pero muchas) soluciones distintas para lidiar con el problema de inyección desde diversos lenguajes de programación:
Pero la más conveniente está dada directamente por nuestro SGBD: las instrucciones preparadas
Una instrucción preparada es una consulta parametrizada que el SGBD puede tener lista antes de ser utilizada
Una instrucción preparada es una consulta parametrizada que el SGBD puede tener lista antes de ser utilizada
$query = "SELECT nombre, apellido, saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = ?
AND password = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("ss", $_POST['username'], $_POST['password']);
$stmt->execute();
$result = $stmt->fetchAll();
String query = "SELECT nombre, apellido, saldo
FROM usuario INNER JOIN cuenta
ON usuario.id = cuenta.usuario_id
WHERE usuario.username = ?
AND password = ?";
PreparedStatement statement = connection.prepareStatement(query);
statement.setInt(1, request.getParameter("username"));
statement.setInt(2, request.getParameter("password"));
ResultSet rs = statement.executeQuery();
PHP
Java
También podemos usarlas dentro de algún ciclo
$query = "INSERT INTO usuario (nombre, apellido) VALUES (?, ?)";
$stmt = $conn->prepare($query);
foreach ($usuarios as $usuario)
{
$stmt->bind_param("ss", $usuario['nombre'], $usuario['apellido']);
$stmt->execute();
}
String query = "INSERT INTO usuario (nombre, apellido) VALUES (?, ?)";
PreparedStatement statement = connection.prepareStatement(query);
for (int u: usuarios)
{
statement.setInt(1, u->getNombre());
statement.setInt(2, u->getApellido());
statement.executeQuery();
}
PHP
Java
También podemos usarlas dentro de una transacción
$sql = "START TRANSACTION";
$conn->query($sql);
$query = "INSERT INTO usuario (nombre, apellido) VALUES (?, ?)";
$stmt = $conn->prepare($query);
foreach ($usuarios as $usuario)
{
$stmt->bind_param("ss", $usuario['nombre'], $usuario['apellido']);
$stmt->execute();
}
$sql = "COMMIT";
$conn->query($sql);
String sql = "START TRANSACTION";
statement.execute(sql);
String query = "INSERT INTO usuario (nombre, apellido) VALUES (?, ?)";
PreparedStatement statement = connection.prepareStatement(query);
for (int u: usuarios)
{
statement.setInt(1, u->getNombre());
statement.setInt(2, u->getApellido());
statement.executeQuery();
}
String sql = "COMMIT";
statement.execute(sql);
PHP
Java
By Gilberto 🦁
Capa de aplicación
Desarrollo visualizaciones y aplicaciones en línea, colaboro con distintos medios digitales