我正在执行一个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()
发布于 2022-11-13 11:19:52
幸运的是,大多数数据库连接器都有查询参数,在这些参数中,您传递变量,而不是自己在查询中提供字符串,以防范您提到的风险。您可以在这里阅读更多内容: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, ));
发布于 2022-11-13 18:02:31
正如阿曼泽在他的答复中正确提到的那样,Python有安全的通径参数机制。
但是,查询中还有其他元素(表名和列名)不支持作为参数(绑定变量),因为JDBC不支持这些元素。
如果这些是来自不受信任的源(或者将来可能是这样),您应该确保验证这些元素。这是一个很好的编码实践,即使你是确定的。
有一些选择可以安全地做到这一点:
如果这不可能(因为这些是用户创建的?):
https://stackoverflow.com/questions/74420254
复制相似问题