python pyodbc SQLite sql 注入
python pyodbc SQLite sql injections
我在我的 python flask 项目中使用 pyodbc 作为 SQLite 数据库连接。
我知道并理解 SQL 注入,但这是我第一次处理它。
我试图执行一些
我有一个函数可以连接我的 database.py 文件中的 SQL 字符串:
def open_issue(self, data_object):
cursor = self.conn.cursor()
# data_object is the issue i get from the user
name = data_object["name"]
text = data_object["text"]
rating_sum = 0
# if the user provides an issue
if name:
# check if issue is already in db
test = cursor.execute(f'''SELECT name FROM issue WHERE name = "{name}"''')
data = test.fetchall()
# if not in db insert
if len(data) == 0:
# insert the issue
cursor.executescript(f'''INSERT INTO issue (name, text, rating_sum)
VALUES ("{name}", "{text}", {rating_sum})''')
else:
print("nothing inserted!")
在 api.py 文件中调用了 open_issue() 函数:
@self.app.route('/open_issue')
def insertdata():
# data sent from client
# data_object = flask.request.json
# unit test dictionary
data_object = {"name": "injection-test-table",
"text": "'; CREATE TABLE 'injected_table-1337';--"}
DB().open_issue(data_object)
“'; CREATE TABLE 'injected_table-1337';--”sql 注入没有创建 injected_table-1337,而是像字符串一样正常插入到注入测试的文本列-table.
所以我真的不知道我对 SQL 注入的标准方式是否安全(这个项目将只在本地托管,但总是欢迎良好的安全性)
其次:pyodbc 有没有办法检查字符串是否包含 sql 语法或符号,这样就不会在我的示例中插入任何内容,或者我是否需要手动检查字符串?
非常感谢
事实证明,使用 SQLite,您遇到 SQL 注入问题的风险要小得多,因为默认情况下 Python 的内置 sqlite3
模块和 SQLite ODBC 驱动程序都允许在单个 .execute
调用中执行多个语句(通常称为“匿名代码块”)。此代码:
thing = "'; CREATE TABLE bobby (id int primary key); --"
sql = f"SELECT * FROM table1 WHERE txt='{thing}'"
crsr.execute(sql)
为 sqlite3 抛出这个
sqlite3.Warning: You can only execute one statement at a time.
这是 SQLite ODBC
pyodbc.Error: ('HY000', '[HY000] only one SQL statement allowed (-1) (SQLExecDirectW)')
不过,您应该遵循最佳做法并使用适当的参数化查询
thing = "'; CREATE TABLE bobby (id int primary key); --"
sql = "SELECT * FROM table1 WHERE txt=?"
crsr.execute(sql, (thing, ))
因为这也将正确处理直接注入会导致错误的参数值,例如
thing = "it's good to avoid SQL injection"
我在我的 python flask 项目中使用 pyodbc 作为 SQLite 数据库连接。 我知道并理解 SQL 注入,但这是我第一次处理它。 我试图执行一些
我有一个函数可以连接我的 database.py 文件中的 SQL 字符串:
def open_issue(self, data_object):
cursor = self.conn.cursor()
# data_object is the issue i get from the user
name = data_object["name"]
text = data_object["text"]
rating_sum = 0
# if the user provides an issue
if name:
# check if issue is already in db
test = cursor.execute(f'''SELECT name FROM issue WHERE name = "{name}"''')
data = test.fetchall()
# if not in db insert
if len(data) == 0:
# insert the issue
cursor.executescript(f'''INSERT INTO issue (name, text, rating_sum)
VALUES ("{name}", "{text}", {rating_sum})''')
else:
print("nothing inserted!")
在 api.py 文件中调用了 open_issue() 函数:
@self.app.route('/open_issue')
def insertdata():
# data sent from client
# data_object = flask.request.json
# unit test dictionary
data_object = {"name": "injection-test-table",
"text": "'; CREATE TABLE 'injected_table-1337';--"}
DB().open_issue(data_object)
“'; CREATE TABLE 'injected_table-1337';--”sql 注入没有创建 injected_table-1337,而是像字符串一样正常插入到注入测试的文本列-table.
所以我真的不知道我对 SQL 注入的标准方式是否安全(这个项目将只在本地托管,但总是欢迎良好的安全性)
其次:pyodbc 有没有办法检查字符串是否包含 sql 语法或符号,这样就不会在我的示例中插入任何内容,或者我是否需要手动检查字符串?
非常感谢
事实证明,使用 SQLite,您遇到 SQL 注入问题的风险要小得多,因为默认情况下 Python 的内置 sqlite3
模块和 SQLite ODBC 驱动程序都允许在单个 .execute
调用中执行多个语句(通常称为“匿名代码块”)。此代码:
thing = "'; CREATE TABLE bobby (id int primary key); --"
sql = f"SELECT * FROM table1 WHERE txt='{thing}'"
crsr.execute(sql)
为 sqlite3 抛出这个
sqlite3.Warning: You can only execute one statement at a time.
这是 SQLite ODBC
pyodbc.Error: ('HY000', '[HY000] only one SQL statement allowed (-1) (SQLExecDirectW)')
不过,您应该遵循最佳做法并使用适当的参数化查询
thing = "'; CREATE TABLE bobby (id int primary key); --"
sql = "SELECT * FROM table1 WHERE txt=?"
crsr.execute(sql, (thing, ))
因为这也将正确处理直接注入会导致错误的参数值,例如
thing = "it's good to avoid SQL injection"