First of all Im pretty new to databases and i started using Python yesterday.
I started playing around with the sqlite3 module ( I used some Sqlite prior to this via DBI in Perl)
I stumbled across the following example on the official Python Sqlite 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()
Why is the first example insecure and the second not?
Lets just say i have some application that stores documents and the user can search the database by the document name.
For this to work i would need an input from the user and then create a query with the keyword/s
I dont get why a tuple should now be more "secure" then a string i mean in both cases the user could input something like "xyz OR 1=1" to display every record.
I hope someone is kind enough to explain this to me. I know this is probably very obvious to someone with experience.
Failure to sanitize inputs can lead to attackers including SQL code in form inputs so they can do any number of interesting things, ranging from deleting information from a database to injecting information.
To sanitize a string input which you want to store to the database (for example a customer name) you need either to escape it or plainly remove any quotes (', ") from it. This effectively prevents classical SQL injection which can happen if you are assembling an SQL query from strings passed by the user.
Data sanitization is the process of removing all dangerous characters from an input string before passing it to the SQL engine. For exampl… Arguably, the best technique to protect against SQL injections is a method called prepared statements.
Parameters are not the same as simple string substitution; they give their values directly to the database without further interpretation:
>>> 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()
[]
With a parameter, you get the same effect as if the value would have been quoted correctly for all special characters (in this case, WHERE x = 'x'' OR 1=1--'
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With