This question already has an answer here:
Is this Python code vulnerable to SQL injection? (SQLite3)
(1 answer)
Closed 9 years ago.
I'm starting to program a Python application that works with databases. Reading about prepared statements, I found how I'm supposed to write them:
...
strSQL = "select * from myTable where aField = $s" % (aValue)
cursor.execute(strSQL)
...
My question is: Isn't this vulnerable to SQL injection? If so, how can I prevent it?
Thank you
You are using the string formatting operator instead of bound SQL parameters, so your code is indeed at risk of SQL injection (once you fix the $s, which I take to be a typo).
The correct form is:
strSQL = "select * from myTable where aField = %s"
cursor.execute(strSQL, [aValue])
The way you have it, absolutely! Here's how you would "help" get around the sql injection
strSQL = "select * from myTable where aField = %s"
cursor.execute(strSQL, [aValue])
Pass the values as a list/tuple to the second argument on the cursor execute
Related
This question already has an answer here:
Python sqlite3 parameterized drop table
(1 answer)
Closed 5 years ago.
I'm trying to use a variable for a table name. I get the error "... near ''myTable'' at line 1
I must not be escaping this right. The double '' in the error seems to be a clue, but I don't get it.
db = MySQLdb.connect("localhost","user","pw","database" )
table = "myTable"
def geno_order(db, table):
cursor = db.cursor() # prepare a cursor object using cursor() method
sql = "SELECT * FROM %s"
cursor.execute(sql, table)
results = cursor.fetchall()
You can't use a parameter for the table name in the execute call. You'll need to use normal Python string interpolation for that:
sql = "SELECT * FROM %s" % table
cursor.execute(sql)
Naturally, you'll need to be extra careful if the table name is coming from user input. To mitigate SQL injection, validate the table name against a list of valid names.
This question already has answers here:
Using a Python variable in MySQL query
(2 answers)
Closed 4 years ago.
I am using PyMySQL to execute SQL query commands from python. My pystyle is pyformat which was found using:
>>> pymysql.paramstyle
pyformat
My db and cursor details are as follows:
>>> MYDB = pymysql.connect(_params_)
>>> cursor = MYDB.cursor()
I then execute a SQL query using,
>>> cursor.execute("SELECT * FROM %(tablename)s", {"tablename": "activity"})
I get an error stating,
ProgrammingError: (1064, u"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the
right syntax to use near '''activity''' at line 1")
On the other hand, the query by itself works,
>>> unsafe_sql = ("Select * from activity")
>>> cursor.execute(unsafe_sql)
>>> 4
I am not sure what is going on with my first query. Any help appreciated.
You can't pass a table name as a parameter to cursor.execute(). Whenever a parameter is a string it quotes it when it substitutes into the query. Use a normal string formatting method, e.g.
cursor.execute("SELECT * FROM %(tablename)s" % {"tablename": "activity"})
This question already has answers here:
How to use variables in SQL statement in Python?
(5 answers)
Closed 5 days ago.
I'm trying to iterate through all the rows in a table named Throughput, but for a specific DeviceName (which I have stored in data['DeviceName']. I've tried the following, but it doesn't work:
for row in cursor.execute("SELECT * FROM Throughput WHERE DeviceName=%s"), %(data['DeviceName']):
EDIT: also tried this but it doesn't work:
for row in cursor.execute("SELECT * FROM Throughput WHERE(DeviceName), values(?)", (data['DeviceName']) ):
EDIT2: A snippet of my final working code:
query = "SELECT * FROM Throughput WHERE DeviceName = '%s'" % data['Device Name']
try:
for row in cursor.execute(query):
You are also able to parameterize statements:
...
cursor.execute("SELECT * FROM Throughput WHERE DeviceName = ?", data['DeviceName'])
...
This a better approach for the following reasons:
Protection against SQL injection (you should always validate user input regardless of whether parameterized or dynamic SQL is used)
You don't have to worry about escaping where clause values with single quotes since parameters are passed to the database separately
SQL is prepared once, subsequent executions of the query use the prepared statement instead of recompiling
I don't know if my problem is similar to yours or not but my problem was because I had written a query like
WHERE date > ?" "OR date NOT LIKE '9%'
and I'd forgotten to put a simple space (' ') either at the end of the 1st line or the end of the 2nd one. Finally I resolved it just with doing this. And the final code looks like:
WHERE date > ? "
"OR date NOT LIKE '9%'
note: pay attention to the final ' ' at the end of the 1st line.
This question already has answers here:
Variable table name in sqlite
(9 answers)
Closed 6 years ago.
I have a program where the user can select what table they want to modify in SQLite. I store the selection in a variable called table, then try and select everything from that table
c.execute('SELECT * FROM ?', (table,))
The program gets stuck at the question mark. It says:
"Sqlite3.OperationalError: near "?": syntax error"
What am I doing wrong?
You can't use parameter substitution for the table name. You need to add the table name to the query string yourself. Something like this:
query = 'SELECT * FROM {}'.format(table)
c.execute(query)
One thing to be mindful of is the source of the value for the table name. If that comes from an untrusted source, e.g. a user, then you need to validate the table name to avoid potential SQL injection attacks. One way might be to construct a parameterised query that looks up the table name from the DB catalogue:
import sqlite3
def exists_table(db, name):
query = "SELECT 1 FROM sqlite_master WHERE type='table' and name = ?"
return db.execute(query, (name,)).fetchone() is not None
This question already has an answer here:
Python sqlite3 parameterized drop table
(1 answer)
Closed 5 years ago.
I'm trying to use a variable for a table name. I get the error "... near ''myTable'' at line 1
I must not be escaping this right. The double '' in the error seems to be a clue, but I don't get it.
db = MySQLdb.connect("localhost","user","pw","database" )
table = "myTable"
def geno_order(db, table):
cursor = db.cursor() # prepare a cursor object using cursor() method
sql = "SELECT * FROM %s"
cursor.execute(sql, table)
results = cursor.fetchall()
You can't use a parameter for the table name in the execute call. You'll need to use normal Python string interpolation for that:
sql = "SELECT * FROM %s" % table
cursor.execute(sql)
Naturally, you'll need to be extra careful if the table name is coming from user input. To mitigate SQL injection, validate the table name against a list of valid names.