NB: This is the fourth post in a series of posts on web application security.
SQL injection is a vector that lets a user insert their own SQL into a statement sent to your database server. The typical example is:
"SELECT * FROM users WHERE username = ‘" + username + "’ AND \
password = ‘" + password ‘"
Then someone submits
' OR 1=1; -- as their password.
To avoid this, use parameterized queries or, better yet, use framework-level functions like ORMs that make it very difficult to do this wrong. In Django, use the auth framework, but even if you wanted to look up users for another reason, use the ORM:
Sometimes ORMs don’t produce the fastest queries, or we want to do complicated joins. That’s fine, there are still tools. Django provides the Queryset.raw() method. Use it correctly:
User.objects.raw(‘SELECT username FROM auth_user WHERE username=%s’,
Other types of Injections
SQL injection is only one type of injection. Much worse are injections that let users run code on your server. PHP’s backtick passthrough and Python’s
subprocess.call are both dangerous places that need to be carefully audited. If possible, they should be avoided completely. If that’s not possible, don’t put user data in there.
eval() is another risky thing to avoid if at all possible.
In Python, the
ast.literal_eval method is both safe and more often than not does whatever it was you thought you needed
eval() to do in the first place.
If you’re running code on the server under any user, even the web process user—which should have almost no permissions—don’t put user data in there. Just don’t do it. Find another way.
- Go to the series index.
- Go to the previous post in the series, CSRF: Cross-Site Request Forgeries.
- Go to the next post in the series, Access Control.