2010-12-15 37 views
0

J'essayais de tester l'unité de connexion de mon système. Mon système est conçu comme celui-ci -SQL, Microsoft SQl

si l'utilisateur entre userid - ABCD et mot de passe passe le serveur prend ces paramètres et prépare une commande SQL et il tire à Microsoft database-

select password from UserInformationTable where userid = 'abcd'; 

La valeur retournée est comparé avec le mot de passe donné et le résultat est ensuite envoyé au client.

I cassé avec succès dans le système en utilisant la méthode suivante -

utilisateur entre userid - <abcd1 or drop table UserInformationTable>. Cela a fonctionné et mon UserInformationTable complet a été abandonné.

Y a-t-il une façon élégante de gérer un tel problème de piratage? Une façon est de détecter 'ou' la sous-chaîne dans l'ID utilisateur, mais je n'ai pas trouvé cela très gracieux. Est-il possible que je puisse restreindre le non. des requêtes dans une déclaration dans Microsoft SQL?

Merci et salutations, Radz

+1

Aussi, est-ce MySQL ou SQL Server et quelle langue utilisez-vous? –

+1

Lire sur l'injection SQL. Alors lisez pourquoi stocker n'importe quel type de mots de passe en clair est mauvais. Ensuite, lisez CodingHorror.com d'aujourd'hui sur la façon dont l'utilisation d'un tiers pour l'authentification est une bonne voie à suivre. – Joe

+0

vous devez utiliser SqlParameters [helplink] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter.aspx) – Raghuveer

Répondre

0

C'est le problème d'injection SQL illustré par le famous "Bobby Tables" cartoon.

Here est quelques informations sur la façon de le réparer pour MS SQL. Lisez particulièrement la réponse de Rook.

0

Utilisez les paramètres dans les requêtes SQL. Ils empêchent automatiquement cela. Quelque chose comme cela en C#:

SqlCommand comm = new SqlCommand(conn); 
comm.CommandText = "SELECT * FROM foo WHERE bar = @id"; 
comm.CommandType = CommandType.Text; 

SqlParameter param = new SqlParameter("@id", DbType.Int64); 
param.Value = 3; // The actual value that replaces @id 

comm.Parameters.Add(param); 

// ... 

Cela ne vaut que pour C#, mais essentiellement tous les systèmes DB modernes et langues en charge les requêtes paramétrées < - google.

Deuxièmement, votre première requête peut être modifiée pour:

SELECT userid FROM users WHERE username = 'foo' AND password = 'bar' 

Ensuite, il suffit de compter le nombre de lignes que vous avez été retourné, si elle est 0, l'utilisateur est entré dans le mot de passe erroné.

0

Vous avez deux problèmes.

  1. Vous êtes soumis à une attaque par injection SQL comme décrit par d'autres utilisateurs. Résolvez ce problème en assainissant votre entrée et/ou en utilisant des requêtes paramétrées.

  2. Vous ne devez ni stocker ni transmettre de mots de passe en texte brut. Pourquoi? Voir cette histoire sur Slashdot. La solution à ce problème consiste à utiliser un cryptage unidirectionnel pour créer un hachage de mot de passe à stocker dans la base de données. Lorsque l'utilisateur tente de se connecter, utilisez le même cryptage sur le mot de passe qu'il fournit, puis recherchez dans votre base de données si une ligne existe avec les mêmes ID utilisateur et mot de passe. Utilisez-vous réellement des paramètres ou concaténez-vous simplement la chaîne de caractères pour l'interrogation?