Laboratorio temático II

Sentencias preparadas

Inyección de código SQL

Cualquier aplicación que interactúe con una base de datos está sujeta a varios riesgos y vulnerabilidades de seguridad

 

El mayor riesgo, en el caso de las bases de datos SQL, es el de la inyección de código

 

La inyección de código SQL (SQL injection) es una técnica que consiste en modificar las consultas SQL que se ejecutan en el servidor a través de los valores que se ingresan en una interfaz y se envían al manejador de bases de datos

Inyección de código SQL

Algunas de las razones por las que podemos tener un riesgo de inyección de código SQL son:

  • Caracteres de espacio filtrados incorrectamente
  • Mal manejo de tipos de datos
  • Pasar valores sin sanitizar a la capa de datos
  • No utilizar una codificación adecuada
  • Tener mezclas entre el código y los datos
  • Depender del uso de comillas, dobles o sencillas, para delimitar cadenas

Inyección de código SQL

    <?php
    $usuario=$_POST['usuario'];
    $password=$_POST['password'];
    $query="SELECT * FROM users WHERE user_name='".$usuario."' AND user_password='".$password"';";
    ?>

Inyección de código SQL

    <?php
    $usuario=$_POST['usuario'];
    $password=$_POST['password'];
    $query="SELECT * FROM users WHERE user_name='".$usuario."' AND user_password='".$password"';";
    ?>

¿Qué sucede si la variable $_POST['usuario'] tiene el siguiente valor?

<?php
$usuario = 'loquesea'
$password = ‘ or ‘a’=’a’ ‘or’

Inyección de código SQL

    <?php
    $usuario=$_POST['usuario'];
    $password=$_POST['password'];
    $query="SELECT * FROM users WHERE user_name='".$usuario."' AND user_password='".$password"';";
    ?>

¿Qué sucede si la variable $_POST['usuario'] tiene el siguiente valor?

<?php
$usuario = 'loquesea'
$password = ‘ or ‘a’=’a’

La consulta se convierte en:

    <?php
    $sqlQuery="SELECT * FROM users WHERE user_name='loquesea' AND user_password='' OR 'a'='a';";
    ?>

Inyección de código SQL

    <?php
    $id = 1;
    $query = "SELECT * FROM users where id=$expected_data";
    ?>

Inyección de código SQL

    <?php
    $id = 1;
    $query = "SELECT * FROM users where id=$expected_data";
    ?>

¿Qué sucede si la variable $id tiene el siguiente valor?

<?php
$id = "1; DROP TABLE users;";

Inyección de código SQL

    <?php
    $id = 1;
    $query = "SELECT * FROM users where id=$expected_data";
    ?>

¿Qué sucede si la variable $id tiene el siguiente valor?

<?php
$id = "1; DROP TABLE users;";

La consulta se convierte en:

    <?php
    $sqlQuery="SELECT * FROM users where id=1; DROP TABLE users;";
    ?>

Sentencias preparadas

Una sentencia preparada (prepared statement) es una consulta SQL precompilada por el servidor SQL

 

La consulta debe estar en un formato parametrizado, de modo que la consulta y los datos se manejen por separado para que el servidor los opere en su propia capa

Sentencias preparadas

    <?php
    $usuario=$_POST['usuario'];
    $password=$_POST['password'];
    
    $stmt = $pdo->prepare("SELECT * FROM users WHERE user_name = :username AND user_password = :password");
    $stmt->bindParam(':username', $usuario);
    $stmt->bindParam(':password', $password);
    $stmt->execute();
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    ?>

Sentencias preparadas

    <?php
    $usuario=$_POST['usuario'];
    $password=$_POST['password'];
    
    $stmt = $pdo->prepare("SELECT * FROM users WHERE user_name = :username AND user_password = :password");
    $stmt->bindParam(':username', $usuario);
    $stmt->bindParam(':password', $password);
    $stmt->execute();
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    ?>
<?php
$usuario = ‘ or ‘a’=’a’ ‘or’
?>

¿Qué sucede si la variable $_POST['usuario'] tiene el siguiente valor?

Sentencias preparadas

    <?php
    $usuario=$_POST['usuario'];
    $password=$_POST['password'];
    
    $stmt = $pdo->prepare("SELECT * FROM users WHERE user_name = :username AND user_password = :password");
    $stmt->bindParam(':username', $usuario);
    $stmt->bindParam(':password', $password);
    $stmt->execute();
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    ?>
<?php
$usuario = ‘ or ‘a’=’a’ ‘or’
?>
    <?php
    "SELECT * FROM users WHERE user_name = '‘ or ‘a’=’a’ ‘or’' AND user_password = "
    ?>

¿Qué sucede si la variable $_POST['usuario'] tiene el siguiente valor?

La consulta se convierte en:

Sentencias preparadas

En términos concretos la forma para evitar ataques de inyección de código es:

  1. Validar y sanitizar cualquier dato de entrada
    • Este proceso siempre debe hacerse del lado del servidor
    • Es normal hacerlo del lado del cliente (por cuestiones de UX) pero los problemas de seguridad deben tratarse en el servidor
    • La validación del servidor generalmente se hace a través de expresiones regulares, aunque depende del tipo de dato
  2. Escribir las consultas de manera parametrizada
  3. Crear las sentencias preparadas
  4. Ligar los parámetros a las sentencias preparadas
  5. Ejecutar la consulta con las sentencias preparadas

Laboratorio temático II: Sentencias preparadas

By Gilberto 🦁

Laboratorio temático II: Sentencias preparadas

Sentencias preparadas

  • 78