2017-02-16 12 views
2

Это admitted что подготовлены заявления обеспечивают хорошую защиту от инъекций SQL и что вручную инъекционного переменной в запрос SQL с помощью PG::Connection#exec является зла и должны никогда быть сделано.Является ли PG :: Connection # exec_params идентичным использованию подготовленного оператора, когда дело доходит до защиты от SQL-инъекций?

Но как насчет PG::Connection#exec_params? Обеспечивает ли тот же уровень защиты от SQL-инъекций, чем подготовленный отчет?

Если он обеспечивает защиту от инъекций sql, всегда ли это true или это правда, только если вы явно привязываете свои параметры?

ответ

2

TL; DR да.

Я не знаю внутренних особенностей драйвера Ruby. Я предполагаю, что есть три стратегии, которые он мог бы использовать. Теоретически можно было бы теоретически допускать атаки SQL-инъекций верхнего уровня (подробнее об этом ниже), но все они могут быть уязвимы для атак с SQL-инъекциями более низкого уровня, как и подготовленные операторы.

Чтобы понять это, вам нужно понять, как PostgreSQL выполняет запрос:

  1. Запрос разобранную в дерево разбора
  2. Параметры используются для планирования запроса
  3. План выполнен
  4. Данные представлены для возврата.

В подготовленных заявлениях план сохранен, но это не то, что делает их безопасными. Что делает их безопасными в отношении атак верхнего уровня, так это то, что параметры отправляются отдельно от запроса, который нужно разобрать.

Первой стратегией могут быть подготовленные на стороне сервера заявления. В этом случае планы будут сохранены и потенциально повторно использованы, что может иметь нежелательные (или желательные) последствия для производительности.

Во-вторых, протокол PostgreSQL позволяет отправлять запросы и параметры отдельно, даже если они не используют подготовленные операторы. Это имеет одинаковые преимущества безопасности, но не позволяет повторное использование плана. Рассматривая код, это выглядит как предпочтительный способ работы этого метода.

В-третьих, вы можете иметь выход на стороне клиента. Это все еще безопаснее, чем все, что вы сделаете сами, так как оно, вероятно, расположено в центре и т. Д. Я знаю, что DBD Perl :: Pg может вернуться к этому, но почти никогда не делает этого. Я не видел резерва, но, возможно, есть один, который я пропустил.

Как правило, я бы сказал, что да, это дает сопоставимые выгоды, даже если используется худший метод.

Примечание. Я продолжаю говорить о нападениях верхнего уровня. Это возможно, если вы вызываете функцию где-нибудь (например, из триггера), которая также может иметь SQL-инъекцию. Это происходит там, где задействован динамический SQL, но обычно это не проблема. Ни один из вышеперечисленных методов не защищает от этого, поскольку этап планирования будет выполняться как часть этапа выполнения выше, и параметры всегда были заполнены.

Вот почему хорошая практика кодирования на всех уровнях приложения важный.

+0

Очень четкий ответ! большое спасибо – Thibauld