提问人:randomguy2443 提问时间:11/13/2022 最后编辑:randomguy2443 更新时间:11/14/2022 访问量:262
如何避免在 Python 中注入 SQL 以对 SQL Server 进行 Upsert 查询?
How to avoid SQL Injection in Python for Upsert Query to SQL Server?
问:
我正在执行一个sql查询,我正在将变量传递到该查询中。在当前上下文中,我将参数值作为 f 字符串传递,但此查询容易受到 sql 注入的影响。我知道有一种方法可以使用存储过程并限制执行查询的用户的权限。但是,有没有办法避免走存储过程路线,也许可以修改此函数以防 SQL 注入?
I have the below query created to execute within a python app.
def sql_gen(tv, kv, join_kv, col_inst, val_inst, val_upd):
sqlstmt = f"""
IF NOT EXISTS (
SELECT *
FROM {tv}
WHERE {kv} = {join_kv}
)
INSERT {tv} (
{col_inst}
)
VALUES (
{val_inst}
)
ELSE
UPDATE {tv}
SET {val_upd}
WHERE {kv} = {join_kv};
"""
engine = create_engine(f"mssql+pymssql://{username}:{password}@{server}/{database}")
connection = engine.raw_connection()
cursor = connection.cursor()
cursor.execute(sqlstmt)
connection.commit()
cursor.close()
答:
0赞
Amanzer
11/13/2022
#1
幸运的是,大多数数据库连接器都有查询参数,您可以在其中传递变量,而不是在查询中自己提供字符串来应对您提到的风险。 您可以在此处阅读更多相关信息: https://realpython.com/prevent-python-sql-injection/#understanding-python-sql-injection
例:
# Vulnerable
cursor.execute("SELECT admin FROM users WHERE username = '" + username + '");
# Safe
cursor.execute("SELECT admin FROM users WHERE username = %s'", (username, ));
0赞
Egret
11/14/2022
#2
正如 Amanzer 在他的回复中正确提到的那样,Python 具有安全传递参数的机制。
但是,查询中还有其他元素(表名和列名)不支持作为参数(绑定变量),因为 JDBC 不支持这些元素。
如果这些元素来自不受信任的来源(或将来可能来自不受信任的来源),则应确保验证这些元素。即使您确定,这是一个很好的编码实践。
有一些选项可以安全地执行此操作:
- 应根据肯定验证来限制表和列 - 确保唯一允许的值是已授权的值
如果这是不可能的(因为这些是用户创建的?
- 应确保表或列名限制 使用一组“安全”字符(字母数字和破折号、 下划线...
- 您应该引用表名/列名 - 在对象两边添加双引号。如果这样做,则需要 小心验证名称中没有引号,并出错 或转义引号。您还需要注意添加引号 将使名称区分大小写。
评论