SQLite Injection
Si votre site permet aux utilisateurs de saisir des données via des pages web et insère cette saisie dans une base de données SQLite, alors vous êtes confronté à un problème de sécurité connu sous le nom d'injection SQL. Ce chapitre expliquera comment empêcher cela et garder vos scripts et vos instructions SQLite sécurisés.
L'injection se produit généralement lorsqu'une saisie utilisateur est demandée, par exemple lorsqu'un utilisateur est invité à saisir son nom, mais qu'il saisit à la place une instruction SQLite, qui s'exécute à son insu sur la base de données.
Ne faites jamais confiance aux données fournies par les utilisateurs, donc ne traitez que les données qui ont été validées. Cette règle est mise en œuvre par la correspondance de motifs. Dans l'exemple ci-dessous, le nom d'utilisateur est limité aux caractères alphanumériques ou aux traits de soulignement, et sa longueur doit être comprise entre 8 et 20 caractères - modifiez ces règles selon vos besoins.
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";
}
Pour démontrer ce problème, considérons cet extrait :
$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username='{$name}'");
L'appel de fonction est destiné à récupérer des enregistrements dans la table users où la colonne name correspond au nom spécifié par l'utilisateur. Dans des circonstances normales,$namene contiendrait que des caractères alphanumériques ou des espaces, comme la chaîne ilia. Mais ici, une toute nouvelle requête est ajoutée à $name. Cet appel à la base de données causera un problème désastreux : la requête DELETE injectée supprimera tous les enregistrements de la table users.
Bien qu'il existe déjà des interfaces de base de données qui n'autorisent pas l'empilement de requêtes ni l'exécution de plusieurs requêtes dans un seul appel de fonction, et que l'appel échouera si vous tentez d'empiler des requêtes, SQLite et PostgreSQL autorisent encore les requêtes empilées, ce qui signifie que toutes les requêtes fournies dans une seule chaîne sont exécutées, ce qui peut entraîner de graves problèmes de sécurité.
Prévention de l'injection SQL
Dans des langages de script tels que PERL et PHP, vous pouvez gérer intelligemment tous les caractères d'échappement. Le langage de programmation PHP fournit une fonction de chaîneSQLite3::escapeString($string)etsqlite_escape_string()pour échapper les caractères d'entrée spéciaux pour SQLite.
Remarque : La version de PHP requise pour utiliser la fonctionsqlite_escape_string()estPHP 5 < 5.4.0。
PHP 5 >= 5.3.0, PHP 7 utilisent la fonction suivante :
SQLite3::escapeString($string);//$string为要转义的字符串
La méthode suivante n'est pas prise en charge dans les dernières versions de PHP :
if (get_magic_quotes_gpc())
{
$name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username='{$name}'");
Bien que l'encodage sécurise les données insérées, il pose problème pour la comparaison de texte simple. Dans les requêtes, pour les colonnes contenant des données binaires, la clauseLIKEn'est pas utilisable.
Veuillez noter que addslashes() ne doit pas être utilisé pour entourer de guillemets des chaînes dans les requêtes SQLite, car cela peut causer des résultats étranges lors de la récupération des données.
Autres extensions