如何减少因注入而遭受网络攻击的脆弱性?

问题描述 投票:0回答:1

我对 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 变量,但我不知道如何使堆栈溢出的现有示例/解决方案适应我的特定用例。如有任何建议,我们将不胜感激。

sql security pyodbc sql-injection
1个回答
0
投票

就注入而言,您现有的代码没有任何问题。

仅当用户数据直接注入查询时才会发生注入。在这里,这并没有发生。发生的情况是,以明确定义的方式(每行一次)注入

?
参数标记的动态列表,并且实际值作为动态参数列表传递。这里绝对没有注入的余地。

但请注意几点:

  • 使用这样的代码确实倾向于将注意力集中在“哦,只是注入数据”。可能值得发表评论,例如
    only paramaters are injected here
  • 如果根本没有要插入的行,那么您会得到无效代码
    ( VALUES )
    ,因此您应该检查这一点。
  • 参数的动态数量意味着您可以针对参数的每种可能变化进行重新编译。如果您实际注入数据,这不会那么多,但仍然是一个问题。
    因此,表值参数或批量插入临时表都是比这更好的选择,但 pyodbc 都不支持。
    fast_executemany
    to_sql
    可能是选项,或者来自外部文件的
    BULK INSERT
  • 参数的最大数量是 2100,不过在此之前你就会遇到性能问题。
© www.soinside.com 2019 - 2024. All rights reserved.