Utilisez l'espace réservé décrit dans Cursor.execute (self, query, args = None)
lors de la construction de requêtes à l'aide du module MySQL-python (MySQLdb) de Python.
query -- string, query to execute on server
args -- optional sequence or mapping, parameters to use with query.
Note: If args is a sequence, then %s must be used as the
parameter placeholder in the query. If a mapping is used,
%(key)s must be used as the placeholder.
Créez le tableau suivant pour le test.
mysql> select * from testdb.person;
+------+--------+
| id | name |
+------+--------+
| 1 | foo |
| 2 | bar |
+------+--------+
bad.py
import MySQLdb
def select(name):
connection = MySQLdb.connect(db='testdb', user='testuser')
cursor = connection.cursor()
cursor.execute("select * from person where name='%s'" % name)
print("[query]")
print(cursor._last_executed)
print("[result]")
result = cursor.fetchall()
for rec in result:
print(rec)
Si vous faites select (" foo ")
, il semble que cela fonctionne bien.
[query]
select * from person where name='foo'
[result]
(1L, 'foo')
Mais si vous faites quelque chose comme select (" foo 'ou name = name - ")
[query]
select * from person where name='foo' or name=name-- '
[result]
(1L, 'foo')
(2L, 'bar')
Et l'injection SQL est terminée.
good.py
import MySQLdb
def select(name):
connection = MySQLdb.connect(db='testdb', user='testuser')
cursor = connection.cursor()
cursor.execute("select * from person where name=%s", name)
print("[query]")
print(cursor._last_executed)
print("[result]")
result = cursor.fetchall()
for rec in result:
print(rec)
J'ai changé uniquement la partie argument de cursor.execute ()
.
select (" foo ")
fonctionne de la même manière que dans l'exemple précédent.
[query]
select * from person where name='foo'
[result]
(1L, 'foo')
Même si vous faites select (" foo'or name = name-- ")
, il s'échappera correctement.
[query]
select * from person where name='foo\' or name=name-- '
[result]
http://stackoverflow.com/questions/1947750/does-python-support-mysql-prepared-statements
Recommended Posts