2017-09-10 4 views
1

Tout d'abord, je suis assez nouveau pour les bases de données et j'ai commencé à utiliser Python hier.Désinfection de l'entrée SQLite

j'ai commencé à jouer avec le module sqlite3 (j'ai utilisé SQLite avant cette via DBI en Perl)

Je suis tombé sur l'exemple suivant sur le Python Sqlite officiel Documentation here

# Never do this -- insecure! 
symbol = 'RHAT' 
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) 

# Do this instead 
t = ('RHAT',) 
c.execute('SELECT * FROM stocks WHERE symbol=?', t) 
print c.fetchone() 

Pourquoi le premier exemple est-il non sécurisé et le second non? Disons simplement que j'ai une application qui stocke des documents et que l'utilisateur peut effectuer une recherche dans la base de données par le nom du document.

Pour ce travail, je besoin d'une entrée de l'utilisateur, puis créer une requête avec le mot-cle/s

Je n'obtiens pas pourquoi un tuple devrait maintenant être plus « sûre », puis une chaîne que je veux dire à la fois Dans certains cas, l'utilisateur peut saisir quelque chose comme "xyz OR 1 = 1" pour afficher chaque enregistrement.

J'espère que quelqu'un est assez aimable pour m'expliquer cela. Je sais que c'est probablement très évident pour quelqu'un avec de l'expérience.

+1

La sauce secrète est dans _how_ le tuple est traité. –

+1

"Dans les deux cas, l'utilisateur peut saisir quelque chose comme" xyz OR 1 = 1 "pour afficher chaque enregistrement" - non, c'est tout le point. S'il vous plaît chercher "injection sql" dans votre moteur de recherche préféré, cela est très largement couvert. – Mat

Répondre

1

Les paramètres sont et non de même que la substitution de chaîne simple; ils donnent leurs valeurs directement à la base de données sans interprétation plus:

>>> import sqlite3 
>>> db=sqlite3.connect(":memory:") 
>>> db.execute("CREATE TABLE t(x)")     
>>> db.execute("INSERT INTO t VALUES('x'),('secret')") 
>>> db.execute("SELECT * FROM t WHERE x = '%s'" % ("x' OR 1=1--",)).fetchall() 
[(u'x',), (u'secret',)] 
>>> db.execute("SELECT * FROM t WHERE x = ?",  ("x' OR 1=1--",)).fetchall() 
[] 

Avec un paramètre, vous obtenez le même effet que si la valeur aurait été cité correctement pour tous les caractères spéciaux (dans ce cas, WHERE x = 'x'' OR 1=1--').

+0

La dernière phrase m'a vraiment expliqué, merci! :) – Simerax