Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this Python code vulnerable to SQL injection? (SQLite3)

As the title suggests, I would like to know if this code is vulnerable to SQL Injection? And if so, is there a better, more secure, way of achieving the same thing?

def add(table,*args):
    statement="INSERT INTO %s VALUES %s" % (table,args)
    cursor.execute(statement)
like image 697
Sheldon Avatar asked Nov 28 '12 19:11

Sheldon


People also ask

Which of the code is vulnerable to SQL injection?

The following code is vulnerable to SQL injection because the user input is concatenated directly into the query: String query = "SELECT * FROM products WHERE category = '"+ input + "'"; Statement statement = connection. createStatement(); ResultSet resultSet = statement. executeQuery(query);

Is SQLite good for Python?

SQLite3 can be integrated with Python using sqlite3 module, which was written by Gerhard Haring. It provides an SQL interface compliant with the DB-API 2.0 specification described by PEP 249. You do not need to install this module separately because it is shipped by default along with Python version 2.5.

How to prevent SQL injection in Python?

The most important way to prevent SQL injection is to avoid vulnerable code and insecure coding practices. Here are a few ways to do that—they will be effective against SQL injection and many other vulnerabilities that can affect your Python code. 1. Insecure Packages

Do you need a separate SQL injection vulnerability for SQLite?

A separate SQL injection vulnerability is usually required 2.2. Defense Against Dark Arts 2.3. The SQLite Developer Policy Toward CVEs 3. Status Of Recent SQLite CVEs 1. Executive Summary CVEs about SQLite probably do not apply to your use of SQLite. All historical vulnerabilities reported against SQLite require at least one of these preconditions:

Are CVEs written against SQLite really vulnerabilities?

Very few CVEs written about SQLite are real vulnerabilities in the sense that they do not give any new capabilities to an attacker. Consider: Almost all CVEs written against SQLite require the ability to inject and run arbitrary SQL.

How are SQL scripts passed into SQLite from an attacker?

The SQL scripts that are passed into SQLite come from the (trusted) application itself, not from an attacker. Sometimes applications contain bugs by which an external attacker can trick the application into sending SQL of the attackers design into the database engine. This is a separate bug in the application called an SQL Injection vulnerability.


1 Answers

Yes, it is. Use something like this to prevent it:

cursor.execute("INSERT INTO table VALUES ?", args)

Note that you cannot enter the table in like this. Ideally the table should be hard coded, in no circumstance should it come from a user input of any kind. You can use a string similar to what you did for the table, but you'd better make 100% certain that a user can't change it somehow... See Can I use parameters for the table name in sqlite3? for more details.

Essentially, you want to put the parameters in the cursor command, because it will make sure to make the data database safe. With your first command, it would be relatively easy to make a special table or args that put something into your SQL code that wasn't safe. See the python pages, and the referenced http://xkcd.com/327/ . Specifically, the python pages quote:

Usually your SQL operations will need to use values from Python variables. You shouldn’t assemble your query using Python’s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack (see http://xkcd.com/327/ for humorous example of what can go wrong).

Instead, use the DB-API’s parameter substitution. Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor’s execute() method. (Other database modules may use a different placeholder, such as %s or :1.)

Basically, someone could set an args that executed another command, something like this:

args="name; DELETE table"

Using cursor.execute will stuff the value given, so that the argument could be as listed, and when you do a query on it, that is exactly what you will get out. XKCD explains this humorously as well.

enter image description here

like image 101
PearsonArtPhoto Avatar answered Oct 02 '22 05:10

PearsonArtPhoto