I know that the code snippets below are vulnerable to SQL Injection because of the .format, but i do not know why. Does anyone understand why this code is vulnerable and where i would start to fix it? I am aware that these code snippets leave the input fields open to execute other malicious commands via SQL Injection but don't know why
cursor.execute("insert into user(username, password)"
" values('{0}', '{1}')".format(username, password))
handle[0].execute("insert into auditlog(userid, event)"
" values({0}, ‘{1}')".format(handle[2],event))
audit((cursor, connection, 0),
"registeration error for {0}”.format(username))
sql="""insert into activitylog(userid, activity, start, stop)
values({0}, '{1}', '{2}', '{3}')
""".format(handle[2], activity, start, stop)
From the docs:
An example SQL injection using your first SQL statement:
If
username
andpassword
are"blah"
the resulting SQL statement is:and there is no problem with this particular statement.
However, if a user is able to enter a value for
password
, perhaps from a HTML form, of:the resulting SQL statement will be:
which is actually 3 statements separated by a semicolon: an insert, a drop table, and then a comment. Some databases, e.g. Postgres will execute all of these statements which results in the user table being dropped. Experimenting with SQLite, however, it seems that SQLite will not allow multiple statements at a time to be executed. Nevertheless there might be other ways to inject SQL. OWASP has a good reference on the topic.
Fixing this is easy, use parameterised queries like this:
Placeholders are added to the query using
?
and the db engine will properly escape these values to avoid SQL injections. The resultant query will be:where the terminating
'
in'blah\''
has been properly escaped. The valuewill be present in the password field for the inserted record.
Whenever you construct SQL statements using string operations and data supplied by an outside user you open yourself up to two kinds of vulnerability:
O'Reilly
. When that's interpolated into the string, the spare apostrophe will make the resulting SQL invalid.