SQLite - Inyección

Si toma la entrada del usuario a través de una página web y la inserta en una base de datos SQLite, existe la posibilidad de que se haya quedado abierto a un problema de seguridad conocido como inyección SQL. En este capítulo, aprenderá cómo ayudar a evitar que esto suceda y cómo proteger sus scripts y declaraciones SQLite.

La inyección generalmente ocurre cuando le pides a un usuario una entrada, como su nombre, y en lugar de un nombre, te dan una declaración SQLite que, sin saberlo, ejecutarás en tu base de datos.

Nunca confíe en los datos proporcionados por el usuario, procese estos datos solo después de la validación; como regla, esto se hace mediante la coincidencia de patrones. En el siguiente ejemplo, el nombre de usuario está restringido a caracteres alfanuméricos más guión bajo y a una longitud de entre 8 y 20 caracteres; modifique estas reglas según sea necesario.

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){
   $db = new SQLiteDatabase('filename');
   $result = @$db->query("SELECT * FROM users WHERE username = $matches[0]");
} else {
   echo "username not accepted";
}

Para demostrar el problema, considere este extracto:

$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username = '{$name}'");

Se supone que la llamada a la función recupera un registro de la tabla de usuarios donde la columna de nombre coincide con el nombre especificado por el usuario. Bajo circunstancias normales,$namesolo contendría caracteres alfanuméricos y quizás espacios, como la cadena ilia. Sin embargo, en este caso, al agregar una consulta completamente nueva a $ name, la llamada a la base de datos se convierte en un desastre: la consulta DELETE inyectada elimina todos los registros de los usuarios.

Hay interfaces de bases de datos que no permiten apilar consultas o ejecutar múltiples consultas en una sola llamada de función. Si intenta apilar consultas, la llamada falla, pero SQLite y PostgreSQL realizan felizmente consultas apiladas, ejecutan todas las consultas proporcionadas en una cadena y crean un problema de seguridad grave.

Prevención de la inyección de SQL

Puede manejar todos los caracteres de escape de forma inteligente en lenguajes de script como PERL y PHP. El lenguaje de programación PHP proporciona la funciónstring sqlite_escape_string() para escapar de los caracteres de entrada que son especiales para SQLite.

if (get_magic_quotes_gpc()) {
   $name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username = '{$name}'");

Aunque la codificación hace que sea seguro insertar los datos, proporcionará comparaciones de texto simples y LIKE cláusulas en sus consultas inutilizables para las columnas que contienen los datos binarios.

Note - addslashes()NO debe usarse para citar sus cadenas para consultas SQLite; dará lugar a resultados extraños al recuperar sus datos.