Вопрос или проблема
Плагины WP.org сообщают, что один из наших плагинов представляет собой угрозу безопасности.
Из patchstack:
Плагин содержит уязвимости SQL Injection из-за неподготовленных
запросов: В функции delete_eto параметр $id используется небезопасно в
операции удаления.Войдите в систему как администратор.
GET
/wp-admin/edit.php?post_type=xxx&page=xxx-templates&action=delete-single&gid=193&_wpnonce=3b166c400aЭто удаляет все записи таблицы wp_options.
Плагин включает экран в wp-admin, доступный только администраторам сайта. На этом экране можно создавать, редактировать и удалять опции.
Это проблемная функция:
function delete_eto( $id ) {
global $wpdb;
$id = absint( $id );
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_id = $id" );
}
От команды плагина:
Передача значения $id через absint() не защитит от
удаления произвольного значения опции.
Значение $id
поступает из GET, так что переменная может быть изменена администратором сайта.
Если я передам имя опции в GET, а затем использую delete_option()
, имя опции тоже может быть изменено на “произвольное значение опции”.
Существует ли решение для этой проблемы при использовании GET или мне следует перейти на использование POST?
Или от меня просто хотят, чтобы я использовал ‘prepare’ в SQL?
Ответ или решение
Уважая сложность и чувствительность темы, давайте рассмотрим проблему использования небезопасных запросов в плагине WordPress, что может привести к SQL-инъекциям и непреднамеренному удалению данных из таблицы wp_options
. Ваша цель — устранить риск произвольного удаления значений, который может повлечь за собой серьезные последствия для восстановления данных и безопасности сайтов.
Теория (Theory):
SQL-инъекции — один из наиболее уязвимых факторов, приводящих к нарушению безопасности веб-приложений. Они возникают, когда приложения позволяют внести недоверенные данные в SQL-запросы, которые затем исполняются на сервере базы данных. В вашем случае, небезопасно обработанная переменная $id
используется в SQL-запросе для удаления записей из таблицы wp_options
, что теоретически может привести к удалению всех настроек сайта.
Использование функции absint()
для приведения значения к положительному целому числу не предотвращает риск SQL-инъекции, так как это преобразование надежно только в контексте фильтрации числовых значений и не защищает сами запросы от их модификации.
Пример (Example):
В коде предоставлена функция:
function delete_eto( $id ) {
global $wpdb;
$id = absint( $id );
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_id = $id" );
}
Проблема в том, что если администратор сайта умышленно изменяет переменную gid
в GET-запросе на нечётное значение, это может потенциально привести к выполнению небезопасных операций в базе данных.
Применение (Application):
Наиболее правильный метод решения этой проблемы — использование функции prepare
для безопасного формирования SQL-запросов. Эта функция защищает от SQL-инъекций, предварительно обрабатывая и экранируя входные данные.
Вот как можно изменить функцию для безопасного использования:
function delete_eto( $id ) {
global $wpdb;
$table_name = $wpdb->options;
// Подготовка безопасного запроса с использованием $wpdb->prepare
$sql = $wpdb->prepare( "DELETE FROM $table_name WHERE option_id = %d", $id );
// Выполняем запрос
$wpdb->query( $sql );
}
Использование $wpdb->prepare
значимо уменьшает риск SQL-инъекций, экранируя переменные подстановки ключевых значений (%d
, %s
, %f
), что автоматически защищает от потенциальной вредоносной деятельности.
Что касается вопроса об использовании метода GET или POST, здесь важно отметить, что POST-запросы более безопасны для передачи чувствительных данных, так как они не отображаются в URL и менее подвержены манипуляциям. Однако корректное экранирование и обработка входных данных остаются актуальными в любом случае для предотвращения уязвимостей.
Подводя итог, настоятельно рекомендуется:
- Перевести запрос на безопасное использование с
prepare
, чтобы устранить возможность SQL-инъекций. - Рассмотреть возможность передачи критически важных данных через POST-запросы для повышения безопасности.
- Провести аудит безопасности по всему плагину и убедиться, что в других частях кода также используются методы защиты для предотвращения аналогичных уязвимостей.
Эти меры значительно снижут риски и обеспечат безопасное использование вашего плагина. Надеюсь, что предоставленная информация окажется полезной в решении вашего вопроса.