Services webmasters
Partenaires
Jeux concours gratuits
 
Modèle de stockage avec chiffrement
<<<
Injection SQL Sécurité
>>>

5.1.5 Sécurité des bases de données
5.1 Sécurité
5 Sécurité
 Manuel PHP

Schéma de base de données
Connexions au serveur de base de données
Modèle de stockage avec chiffrement
->Injection SQL

5.1.5.4 Injection SQL

De nombreux développeurs web ne sont pas conscients des possibilités de manipulation des requêtes SQL, et supposent que les requêtes SQL sont des commandes sûres. Cela signifie qu'une requête SQL est capable de contourner les contrôles et vérifications, comme par exemple les identifications et authentifications, et parfois, les requêtes SQL ont accès aux commandes d'administration.

L'injection SQL directe est une technique où un pirate modifie une requête SQL existante pour afficher des données cachées, ou pour écraser des valeurs importantes, ou encore exécuter des commandes dangereuses pour la base. Cela se fait lorsque l'application prend les données envoyées par l'internaute, et l'utilise directement pour contruire une requête SQL. Les exemples ci-dessous sont basés sur une histoire vraie, malheureusement.

Avec le manque de vérification des données de l'internaute et la connexion au serveur avec des droits de super utilisateur, le pirate peut créer des utilisateurs, et créer un autre super utilisateur.
Séparation des résultats en pages, et créer des administrateurs (PostgreSQL et MySQL)

$offset = argv[0]; // Attention, aucune validation!
$query  = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
// avec PostgreSQL
$result = pg_exec($conn, $query);
// avec MySQL
$result = mysql_query($query);
Un utilisateur normal clique sur les boutons 'suivant' et 'précédent', qui sont alors placés dans la variable $offset , encodée dans l'URL. Le script s'attend à ce que la variable $offset soit alors un nombre décimal. Cependant, il est possible de modifier l'URL en ajoutant une nouvelle valeur, au format URL, comme ceci :

// cas de PostgreSQL
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
    select 'crack', usesysid, 't','t','crack'
    from pg_shadow where usename='postgres';
--

// cas de MySQL
0;
UPDATE user SET Password=PASSWORD('crack') WHERE user='root';
FLUSH PRIVILEGES;
Si cela arrive, le script va créer un nouveau super utilisateur. Notez que la valeur 0; sert à terminer la requête originale et la terminer correctement.

Note

C'est une techinque répandue que de forcer l'analyseur SQL d'ignorer le reste de la requête, en utilisant les symboles -- pour mettre en commentaire.

Un moyen possible pour accéder aux mots de passe est de contourner la recherche de page. Ce que le pirate doit faire, c'est simplement voir si une variable du formulaire est utilisée dans la requête, et si elle est mal gérée. Ces variables peuvent avoir été configurées dans une page précédente pour être utilisées dans les clauses WHERE, ORDER BY, LIMIT et OFFSET des requêtes SELECT . Si votre base de données supporte les commandes UNION , le pirate peut essayer d'ajouter une requête entière pour lister les mots de passe dans n'importe quelle table. Utiliser la technique des mots de passe chiffrés est fortement recommandé.
Liste d'articles ... et ajout de mot de passe

$query  = "SELECT id, name, inserted, size FROM products
                  WHERE size = '$size'
                  ORDER BY $order LIMIT $limit, $offset;";
$result = odbc_exec($conn, $query);
La partie statique de la requête, combinée avec une autre requête SELECT , va révéler les mots de passe :
Révélation des mots de passe

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--
Si cette requête (exploitant les ' et -- ) est affectée à une variable utilisée dans $query , l'injection SQL va arriver.

Les commandes UPDATE sont aussi sujettes à des attaques de votre base de données. Ces requêtes peuvent aussi introduire toute une nouvelle requête dans votre commande initiale. Mais en plus, le pirate peut jouer sur la commande SET . Dans ce cas, il doit connaitre un peu votre base de données. Cela peut se deviner en examinant les noms de variables dans les formulaires, ou simplement, en testant les cas les plus classiques. Il n'y a pas beaucoup de conventions de nommination pour stocker des noms d'utilisateurs et des mots de passe.
Modifier un mot de passe ... et gain de droits!

$query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
Mais un internaute fourbe peut envoyer une valeur telle que ' or uid like '%admin%'; -- dans $uid pour modifier le mot de passe utilisateur, ou simplement, utiliser la variable $pwd avec la valeur "hehehe', admin='yes', trusted=100 " (avec l'espace final) pour obtenir des droits supplémentaires. La requête sera alors devenue :
Une requête et son injection

// $uid == ' or uid like'%admin%'; --
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%'; --";

// $pwd == "hehehe', admin='yes', trusted=100 "
$query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE ...;"

C'est un exemple terrible d'acquisition de droits d'administrateur sur un serveur de base de données.
Attaque d'un serveur de bases de données (MSSQL Server)

$query  = "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
Si le pirate injecte la valeur a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- dans la variable $prod , alors la requête $query devient :
Attaque d'un serveur de base de données (MSSQL Server) - 2

$query  = "SELECT * FROM products
                    WHERE id LIKE '%a%'
                    exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query);
MSSQL Server exécute les requêtes SQL en lot, y compris la commande d'ajout d'un nouvel utilisateur à la base de données locale. Si cette application fonctionnait en tant que sa et que le service MSSQLSERVER disposait de niveau de droits suffisant, le pirate dispose désormais d'un compte avec accès au serveur.

Note

Certains des exemples ci-dessus sont spécifiques à certains serveurs de bases de données. Cela n'empêche pas des attaques similaires d'être possibles sur d'autres produits. Votre base de données sera alors vulnérable d'une autre manière.

Sommaire :

<< Injection SQL >>
Modèle de stockage avec chiffrement Sécurité des bases de données Sécurité
Services webmasters
Les manuels
 
CoursPHP.com - Reproduction interdite -