Top Banner
SQL Injection Defense in Python Edgar Román [email protected] October 4, 2011
18

SQL Injection Defense in Python Edgar Román [email protected] October 4, 2011.

Dec 18, 2015

Download

Documents

Ashlee Carr
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

SQL Injection Defense in Python

Edgar Romá[email protected]

October 4, 2011

Page 2: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

What is SQL Injection?Unauthorized database access by an external source using specially crafted code to piggyback on standard user input to bypass normal protections.

Why?• Gain access to restricted website areas• Query unauthorized data• Delete or corrupt data

Page 3: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

import MySQLdb

def book_search_view(request): if 'bookname' not in request.GET:

raise Http404 conn = MySQLdb.connect (host = "localhost", user = "testuser",

passwd = "testpass", db = "test") cursor = conn.cursor () name = request.GET['bookname'] cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" % name) row = cursor.fetchone ()

cursor.close ()conn.close () return render_to_response('booklist.html', row, context_instance=RequestContext(request))

Page 4: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

• Normal SQL – name=“Moby Dick”

SELECT * FROM table_books WHERE book_name = ‘Moby Dick’

• SQL Injection – bad day– name=“1’; SELECT * from Users; --”

SELECT * FROM table_books WHERE book_name = ‘1’; SELECT * from Users; --’

• SQL Injection 2 – really bad day– name=“1’; DROP TABLE Users; --”

SELECT * FROM table_books WHERE book_name = ‘1’; DROP TABLE Users; --’

Page 5: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Security is about multiple layers

Page 6: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Multiple Layers

• Assume the worst and plan for it• Coding protection is only one layer

– Which we will focus on for this presentation

• Database lockdown– User partitioning– Password protection

• But there are other attacks too: Open Web Application Security Project (OWASP)– https://www.owasp.org/

Page 7: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

General approaches to SQL Injection Defense

• Escape User Input• White Lists• Stored Procs• Parameterized Queries

Page 8: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Escape User Input

• Hard to do right• You’ll probably screw it up if you don’t

cover all the cases– So don’t write your own regex

• MySQLdb.escape_string– Pro: Handles almost all encoding

evasions– Con: Error prone because it depends on

humans to always use it

Page 9: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

import MySQLdb

def book_search_view(request): if 'bookname' not in request.GET:

raise Http404 conn = MySQLdb.connect (host = "localhost", user = "testuser",

passwd = "testpass", db = "test") cursor = conn.cursor () name = MySQLdb.escape_string(request.GET['bookname'] )cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" % name) row = cursor.fetchone ()

cursor.close ()conn.close () return render_to_response('booklist.html', row, context_instance=RequestContext(request))

Page 10: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

What does the escaped version look like?

• SQL Injection – bad day– name=“1’; SELECT * from Users; --”

SELECT * FROM table_books WHERE book_name = ‘1\’; SELECT * from Users; --’

• SQL Injection 2 – really bad day– name=“1’; DROP TABLE Users; --”

SELECT * FROM table_books WHERE book_name = ‘1\’;DROP TABLE Users; --’

Page 11: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Evasion Techniques

http://www.f5.com/pdf/white-papers/sql-injection-detection-wp.pdf

Page 12: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Even more Evasion Techniques

• Multibyte atttacks– http://

shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

– http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html

• Even the experts don’t get it right– MySQL patches bugs in their escaping

routines

Page 13: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

White List

• Scrub data to a known set of inputs• Pros

– Works well for variables with limited range

– Fast• Cons

– Can only be used in customized locations

– Error prone• You might forgot• Or the intern might not understand

• Example: user id must only contain 6 numbers

Page 14: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Stored Procedures

• Use the inherent store procedure capabilities

• Pros– Forces parameterization of all user input

• Cons– Can still be bypassed if sql string is

generated in code and passed to stored procedure

– Not portable between databases

Page 15: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Parameterized Queries

• Use DB API (mysqldb.execute) properly• Use Django ORM• Use SQLAlchemy (pylons, flask)

– Really have to work hard to expose yourself

• Pros– Generally easier to model data

• Cons– ORMs sometimes limit advanced SQL

• Bottom line: use a framework!

Page 16: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

MySQLdb.execute

Bad:cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" % name)

Good:cursor.execute ("SELECT * FROM table_books WHERE book_name = ‘%s’" , name)

Seriously?

Yes

Page 17: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Django ORM

• Automatically escapes all input parameters

• Be aware of extra() method – this is raw!• More info

– http://www.djangobook.com/en/2.0/chapter20/

Page 18: SQL Injection Defense in Python Edgar Román emroman@pbs.org October 4, 2011.

Conclusions

• Use a db framework• If possible, white list your inputs• Be careful if writing raw SQL

http://xkcd.com/327/