Почему PSYCOPG2 по -прежнему разрешает инъекцию SQL с динамически сконструированными именами таблицPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Почему PSYCOPG2 по -прежнему разрешает инъекцию SQL с динамически сконструированными именами таблиц

Сообщение Anonymous »

Я разрабатываю мультитенантное веб-приложение Python, где пользователи должны запросить различные таблицы баз данных на основе контекста их клиента. Задача заключается в создании безопасных запросов SQL, когда имена таблиц должны быть динамически определены во время выполнения. Основная проблема заключается в том, что, хотя параметризованные запросы PSYCOPG2 эффективно предотвращают инъекцию SQL для значений данных, их нельзя использовать для имен таблиц или столбцов. Когда я пытаюсь параметризовать имя таблицы с использованием стандартных заполнителей, PostgreSQL бросает синтаксисную ошибку, поскольку идентификаторы (имена таблицы/столбцов) не могут быть параметризованы так же, как и значения. Это оставляет меня в ситуации, когда я должен динамически построить строки SQL, что традиционно открывает дверь для атак SQL -инъекций. Например, если злоумышленник может управлять вводом имени таблицы, он может потенциально ввести вредоносный код SQL, который выполняется наряду с предполагаемым запросом. < /P>
Я обнаружил psycopg2. 

Код: Выделить всё

sql.Identifier()
Функция, которая утверждает, что для безопасного обработки динамических идентификаторов, но мне нужно понять его ограничения и необходимы ли дополнительные проверки. Приложение обрабатывает конфиденциальные финансовые данные для нескольких клиентов, поэтому безопасность имеет первостепенное значение, но мне также необходимо поддерживать хорошую производительность и обслуживаемость кода. < /P>

Код: Выделить всё

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()
и 

Код: Выделить всё

sql.Identifier()
по сравнению с регулярными параметризованными запросами?



Подробнее здесь: https://stackoverflow.com/questions/796 ... ed-table-n
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»