在 python 中使用字典更新 mysql 表条目的安全方法(防止 SQL 注入)

Safe way to update a mysql table entry with a dictionary in python (safeguarding against SQL injection)

提问人:Dominique Paul 提问时间:3/24/2023 最后编辑:Bill KarwinDominique Paul 更新时间:3/24/2023 访问量:59

问:

我正在为我的 Web 应用程序编写一个帮助程序函数,该函数根据从外部 API(不是用户输入)获取的一些信息更新数据库。我有以下代码,但它被 Bandit python 包标记为“不安全”。

理想情况下,我可以以一种硬编码的方式编写函数,以便对要更新的列进行硬编码,但我认为它也应该是动态的。

这是更新表的安全方法(不可能进行 sql 注入)吗?

import mysql.connector as database

def update_message_by_uid(uid: str, update_dict: dict) -> None:

    # Fetches the previous entry from the database using the unique identifier
    message_info_dict = get_message_by_uid(uid)

    # check that all the keys of the update dict are also in the original dict
    assert set(update_dict.keys()) <= set(
        message_info_dict.keys()
    ), "Some of the keys in the dictionary passed are not valid database columns"

    # We update the entry for all entries in the dictionary containing the updates
    statement = 'UPDATE messages SET {}  WHERE uid = %s'.format(", ".join('{}=%s'.format(k) for k in update_dict))


    # Concatenates the values of the dict with the unique identifier to pass it to the execution method as one variable
    data = list(update_dict.values()) + [uid]

    cursor.execute(statement, data)
python sql sql 注入 mysql 连接器

评论

1赞 Your Common Sense 3/24/2023
您的代码不是很理想,但很安全。这些漏洞扫描程序非常愚蠢。

答:

1赞 Bill Karwin 3/24/2023 #1

如果列名是 SQL 保留关键字或包含空格、标点符号或国际字符,则应将列名放在反引号中。此外,请确保将列名称中的文字反引号字符替换为两个反引号。

assignments = ", ".join(f"`{k.replace('`', '``')}`=%s" for k in update_dict)
statement = f"UPDATE messages SET {assignments}  WHERE uid = %s"

我更喜欢使用 f-strings 而不是 format()。