Я обнаружил psycopg2.
Код: Выделить всё
sql.Identifier()
Код: Выделить всё
import psycopg2
def get_user_data(connection, table_name, user_id):
query = f"SELECT * FROM {table_name} WHERE user_id = %s"
cursor = connection.cursor()
cursor.execute(query, (user_id,))
return cursor.fetchall()
#See an example of the security risk:
malicious_table = "users; DROP TABLE users; --"
get_user_data(conn, malicious_table, 123) #This would execute the DROP command
< /code>
I have tried doing the direct parameterization:
cursor.execute("SELECT * FROM %s WHERE user_id = %s", (table_name, user_id))
< /code>
Я ожидал, что запрос безопасно выполнит с именем таблицы должным образом.psycopg2.errors.SyntaxError: syntax error at or near "$1"< /code> < /p>
PostgreSQL не допускает параметризованных идентификаторов.
Я пробовал форматирование F-String, также попробовал использование SQL.Identifier, как показано ниже: < /p>
from psycopg2 import sql
query = sql.SQL("SELECT * FROM {} WHERE user_id = %s").format(sql.Identifier(table_name))
cursor.execute(query, (user_id,))
< /code>
Это работает, но я не уверен в случаях Edge < /p>
Whitelist + SQL.Identifier () показан ниже < /p>
ALLOWED_TABLES = {'client_1_transactions', 'client_2_transactions'}
if table_name not in ALLOWED_TABLES:
raise ValueError(f"Invalid table: {table_name}")
< /code>
Я думаю, что WhiteList + SQL.Identifier () - это избыток, хотя не уверен. psycopg2.sql.Identifier()
Код: Выделить всё
sql.SQL()
Код: Выделить всё
sql.Identifier()
Подробнее здесь: https://stackoverflow.com/questions/796 ... ed-table-n