search

Home  >  Q&A  >  body text

Safe way to update mysql table entries using dictionary in python (prevent SQL injection)

I'm writing a helper function for my web application that updates the database based on some information obtained from an external API (not user input). I have the following code, but it is marked as "unsafe" by the Bandit python package.

Ideally I could write a function in such a way that I hardcode the columns to be updated, but I think it should be possible to do this dynamically as well.

Is this a safe way to update a table (no SQL injection possible)?

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)

P粉627427202P粉627427202453 days ago694

reply all(1)I'll reply

  • P粉926174288

    P粉9261742882023-09-09 17:22:57

    You should enclose column names in backticks in case the column name is a SQL reserved keyword or contains spaces, punctuation, or international characters. Also make sure that the backtick characters in the column names are replaced with two backticks.

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

    I prefer using f string instead of format().

    reply
    0
  • Cancelreply