SQLite Inyección

Si su sitio permite a los usuarios ingresar datos a través de una página web, y el contenido ingresado se inserta en la base de datos SQLite, entonces se enfrenta a un problema de seguridad llamado inyección SQL. Este capítulo le explicará cómo prevenir esta situación y garantizar la seguridad de los scripts y las sentencias SQLite.

La inyección generalmente ocurre cuando se solicita la entrada del usuario; por ejemplo, se requiere que el usuario ingrese su nombre, pero el usuario ingresa una sentencia SQLite, y esta sentencia se ejecuta en la base de datos sin que nadie lo note.

Nunca confíe en los datos proporcionados por el usuario, por lo tanto, solo procese los datos que hayan sido validados. Esta regla se implementa mediante la coincidencia de patrones. En el siguiente ejemplo, el nombre de usuario (username) está restringido a caracteres alfanuméricos o guiones bajos, y la longitud debe ser de 8 a 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 este problema, considere este extracto:

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

La llamada a la función es para recuperar de la tabla de usuarios los registros donde el valor de la columna name coincide con el nombre especificado por el usuario. En circunstancias normales,$namesolo contiene caracteres alfanuméricos o espacios, como la cadena 'ilia'. Pero aquí, se agrega una consulta completamente nueva a $name, y esta llamada a la base de datos causará un problema catastrófico: la consulta DELETE inyectada eliminará todos los registros de users.

Aunque ya existen interfaces de base de datos que no permiten apilar consultas ni ejecutar múltiples consultas en una sola llamada a función, y si se intenta apilar consultas se producirá un error, SQLite y PostgreSQL sí permiten consultas apiladas, es decir, ejecutan todas las consultas proporcionadas en una sola cadena, lo que puede provocar graves problemas de seguridad.

Prevención de la inyección SQL

En los lenguajes de script como PERL y PHP, puede manejar hábilmente todos los caracteres de escape. El lenguaje de programación PHP proporciona funciones de cadenaSQLite3::escapeString($string)ysqlite_escape_string()para escapar los caracteres de entrada especiales para SQLite.

Nota: el uso de la funciónsqlite_escape_string()la versión de PHP requerida esPHP 5 < 5.4.0。

Versión superior: PHP 5 >= 5.3.0, PHP 7. Utilice la función anterior:

SQLite3::escapeString($string);//$string为要转义的字符串

Las siguientes formas no son compatibles en las versiones más recientes de PHP:

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 la inserción de datos sea segura, esta presenta una comparación de texto simple; en las consultas, para columnas que contienen datos binarios,LIKEla cláusula no está disponible.

Tenga en cuenta que addslashes() no debe usarse para entrecomillar cadenas en consultas SQLite, ya que puede provocar resultados extraños al recuperar datos.

Otras extensiones