Usually I used to write mysql query in python this way:
query = ".."
cursor.execute(query)But it can't prevent sql injection. Check this example: (It will be better if you create a table named user_info with the fields: id, name, email and populate the table with some data.)
import MySQLdb
try:
conn = MySQLdb.connect (host = "localhost",
user = "uname",
passwd = "pass",
db = "mydb")
cursor = conn.cursor()
email = "' OR '1'='1"
query = "SELECT * FROM user_info WHERE email = '" + email + "'"
print query
cursor.execute(query)
if cursor.rowcount > 0:
print cursor.fetchall()
else:
print "no item found"
except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[0], e.args[1])
It will show all records from user_info table! Because the query
SELECT * FROM user_info WHERE email = '' OR '1'='1' gets executed.Now if you run the following code this won't happen:
import MySQLdb
try:
conn = MySQLdb.connect (host = "localhost",
user = "uname",
passwd = "pass",
db = "mydb")
cursor = conn.cursor()
email = "' OR '1'='1"
cursor.execute("SELECT * FROM user_info WHERE email = %s", email)
if cursor.rowcount > 0:
print cursor.fetchall()
else:
print "no item found"
except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[0], e.args[1])
It displays "no item found". It is secured as it lets the MySQLdb library to handle the necessary checking. Here is the format:
cursor.execute("... %s ...%s", (param1, param2))Do you have any more suggestion to prevent sql injection while coding in Python thus improving security?
1 comments:
if you use mysqldb directly %s is the right way to escape injections in pure sql, but generally i suggest to use an orm (like sqlalchemy) for general security, modularity and usability purpose.
Post a Comment