我对 SQL 注入知之甚少,并且可能还有其他我不知道的威胁来窃取公司数据,我如何使这个 python 代码在安全方面更好?
merge_query = """
MERGE INTO sql_table_name AS Target
USING (
VALUES {}
) AS Source (transaction_year, month_num, month_name, price_nt)
ON Target.transaction_year = Source.transaction_year
AND Target.month_num = Source.month_num
WHEN MATCHED AND (Target.month_name != Source.month_name OR Target.price_nt != Source.price_nt) THEN
UPDATE SET Target.month_name = Source.month_name, Target.price_nt = Source.price_nt
WHEN NOT MATCHED THEN
INSERT (transaction_year, month_num, month_name, price_nt) VALUES (Source.transaction_year, Source.month_num, Source.month_name, Source.price_nt);
""".format(','.join(['(?,?,?,?)' for _ in range(len(data))]))
params = [item for sublist in data for item in sublist]
try:
obj_crsr.execute(merge_query, params)
except Exception as e:
obj_crsr.rollback()
print(e)
print("Transaction rolled back")
else:
obj_cnxn.commit()
obj_crsr.close()
obj_cnxn.close()
此 Python 代码以以下格式给出数据:
[(2023, M12, December, 541.44),
(2023, M11, November, 486.64),
(2023, M10, October, 468.23),
(2023, M09, September, 478.80),
(2023, M08, August, 475.41)]
然后转换为 params 变量中的列表。该数据如下所示:
['2023', 'M12', 'December', '541.442', '2023', 'M11', 'November', '486.639', '2023', 'M10', 'October', '468.226', '2023', 'M09', 'September', '478.802', '2023', 'M08', 'August', '475.411']
这是我发现在尝试使用 PYODBC 将数据合并到现有表中时唯一有效的方法。我听说过参数化查询或命名 sql 变量,但我不知道如何使堆栈溢出的现有示例/解决方案适应我的特定用例。如有任何建议,我们将不胜感激。
就注入而言,您现有的代码没有任何问题。
仅当用户数据直接注入查询时才会发生注入。在这里,这并没有发生。发生的情况是,以明确定义的方式(每行一次)注入
?
参数标记的动态列表,并且实际值作为动态参数列表传递。这里绝对没有注入的余地。
但请注意几点:
only paramaters are injected here
。( VALUES )
,因此您应该检查这一点。fast_executemany
或 to_sql
可能是选项,或者来自外部文件的 BULK INSERT
。