27

If a lamer input is inserted into an SQL query directly, the application becomes vulnerable to SQL injection, like in the following example:

dinossauro = request.GET['username']

sql = "SELECT * FROM user_contacts WHERE username = '%s';" % username

To drop the tables or anything -- making the query:

INSERT INTO table (column) VALUES('`**`value'); DROP TABLE table;--`**`')

What may one do to prevent this?

2
  • 3
    May I ask you why are you manually writing sql queries instead of using django Models? Commented Dec 9, 2013 at 10:26
  • 2
    The django ORM, outside of raw and extra will escape your queries for you. See the security docs. Commented Dec 9, 2013 at 10:28

3 Answers 3

16

First, you probably should just use Django ORM, it will prevent any possibility of SQL injection.

If for any reason you can't or don't want to then you should use Python Database API. Here is the way you usually do that in Django:

from django.db import connection

cursor = connection.cursor()
cursor.execute('insert into table (column) values (%s)', (dinosaur,))
cursor.close()

You can also use handy python package to reduce the boilerplate:

from handy.db import do_sql

do_sql('insert into table (column) values (%s)', (dinosaur,))
Sign up to request clarification or add additional context in comments.

Comments

6

From the Django Docs:

SQL injection protection

SQL injection is a type of attack where a malicious user is able to execute arbitrary SQL code on a database. This can result in records being deleted or data leakage.

By using Django’s querysets, the resulting SQL will be properly escaped by the underlying database driver. However, Django also gives developers power to write raw queries or execute custom sql. These capabilities should be used sparingly and you should always be careful to properly escape any parameters that the user can control. In addition, you should exercise caution when using extra().

Comments

4

If you are using .extra() the syntax is:

YourModel.objects.extra(where=['title LIKE %s'], params=['%123%321%'])

Repeating here from this answer as this is hard to find, and the docs that say "you should always be careful to properly escape any parameters" do not go on to say how to properly escape them!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.