Будьте бдительны: функции PHP и WordPress, которые могут сделать ваш сайт небезопасным

Содержание скрыть

Безопасность WordPress (или любой) веб-сайт является многогранной проблемой. Самый важный шаг, который каждый может предпринять, чтобы убедиться, что сайт является безопасным, чтобы иметь в виду, что ни один процесс или метод не является достаточным, чтобы обеспечить ничего плохого не происходит. Но есть вещи, которые вы можете сделать, чтобы помочь. Один из них должен быть на вахте, в коде, который вы пишете, и коде других, который вы развертываете, для функций, которые могут иметь негативные последствия. В этой статье мы рассмотрим именно те функции, которые разработчик WordPress должен ясно продумать перед использованием.

WordPress сам обеспечивает значительную библиотеку функций, некоторые из которых могут быть опасны. Помимо этого, Есть много функций PHP, что WordPress (PHP) разработчик будет использовать с некоторой частотой, которые могут быть опасны при использовании.

Все эти функции имеют законное и безопасное использование, но они также являются функциями, которые могут облегчить использование кода в плохих целях. Мы рассмотрим вещи, которые, скорее всего, являются причиной уязвимости безопасности, и почему вы должны следить за ними. Мы сначала запустить вниз ФУНКЦИи PHP в вашем коде, что плохие актеры могут использовать для зла, а затем говорить о WordPress конкретных функций PHP, которые также могут вызвать головную боль.

ФУНКЦИи PHP, чтобы остерегайться

Как мы уже говорили, PHP содержит много простых в использовании функций. Некоторые из этих функций печально известны легкостью, с которой люди могут делать плохие вещи с ними. Все эти функции имеют надлежащее использование, но будьте осторожны, как вы используете их и как другой код, который вы тянете в проект делает.

Мы собираемся предположить, что у вас уже есть магические котировки и регистрировать глобальные выключены, если ваша версия PHP поддерживает их. Они были выключены по умолчанию в PHP 5 и вверх, но могут быть включены для версий ниже 5.4. Немногие хосты разрешили это, но я не думаю, что статья безопасности PHP действительно полна без их включения.

Или упоминание о том, что PHP 5.6 является последней версией 5.x все еще с постоянной поддержкой безопасности. Вы должны быть на нем, по крайней мере. И вы должны иметь план, чтобы перейти на PHP 7 до 5,6 поддержка заканчивается в конце 2018 года.

После этого, вы просто некоторые рискованные функции для решения. Начиная с…

extractПлохая новость, особенно на $_POST или аналогичные

К счастью, использование extract функции PHP в значительной степени упал в немилость. Суть его использования заключалась в том, что вы могли запускать его на массиве данных, и его пары ключей-ценности стали бы живыми переменными в коде. Сооо

$arr = array(
    'red' => 5
);
extract($arr);
echo $red; // 5

будет работать. Это здорово, но это также очень опасно, если вы извлечения $_GET $_POST , и т.д. В этих случаях вы по существу воссоздаете register_globals проблему самостоятельно: внешний злоумышленник может легко изменить переменные значения, добавив строку запроса или поле формы. Лучшее решение простое: не используйте extract .

Если вы создаете массив, который вы извлекаете сами, это не проблема безопасности в extract использовании, а в некоторых случаях, это может быть полезно. Но все виды его использования имеют проблему запутанной будущих читателей. Создание массива и вызова extract является более запутанным, чем просто объявление переменных. Поэтому я призываю вас делать ручные декларации вместо этого, если это совершенно неосуществимо.

Если вы должны использовать extract на входе пользователя, вы всегда должны использовать EXTR_SKIP флаг. Это все еще имеет проблему запутанности, но оно получает освобожданным от возможности что ваши preset значения могут быть изменены злонамеренным аутсайдером через просто строку запроса или изменение формы паутины. (Потому что он «пропускает» уже установленные значения.)

«Это eval зло», потому что произвольный код страшно

eval в PHP и почти любой другой язык, который несет его всегда высоко в списках, как это. И не зря. Официальная документация PHP о PHP.net говорит, что это довольно откровенно:

ВНИМАНИЕ: Конструкция языка eval() очень опасна, потому что позволяет выполнять произвольный код PHP. Таким образом, его использование не рекомендуется. Если вы тщательно проверили, что нет другого выбора, кроме как использовать эту конструкцию, обратите особое внимание, чтобы не передавать в нее данные, предоставленные пользователем, без надлежащей проверки их заранее.

evalпозволяет запускать любую произвольную строку в вашей программе, как будто это код PHP. Это означает, что это полезно для «мета-программирования», где вы строите программу, которая может сама построить программу. Это также очень опасно, потому что если вы когда-нибудь позволить произвольных источников (например, текстовый ящик на веб-странице), которые будут переданы сразу же eval строки оценщика, вы вдруг сделал это тривиально легко для злоумышленника, чтобы сделать почти все, что PHP может сделать на вашем сервере. Это включает в себя, очевидно, подключение к базе данных, удалять файлы, и почти все, что кто-то может сделать, когда SSHed в машину. Это плохо.

Если вы должны использовать eval в программе, вы должны изо ставить перед собой дорогу, чтобы убедиться, что вы не позволяете произвольного пользовательского ввода, которые будут переданы в нее. И если вы должны разрешить произвольный доступ пользователей к входным eval данным, ограничить то, что они могут сделать через черный список команд вы не позволяете им работать, или (лучше, но гораздо труднее реализовать) белый список, который только команды вы считаете безопасными. Более того, допускаются только небольшое количество конкретных изменений параметров, например, только проверенные целые числа.

Но всегда имейте в виду эту строку от Расмуса Лердорфа, основателя PHP:

«Если «eval()» является ответом, вы почти наверняка задаете неправильный вопрос».

Вариации наeval

Есть, в дополнение к хорошо известным eval , целый ряд других способов, что PHP исторически поддерживает строки-оценки, как код. Два, которые являются наиболее актуальными для разработчиков WordPress preg_replace с /e модификатором, и create_function . Каждый работает немного по-разному, и preg_replace после PHP 5.5.0 не работает вообще. (PHP 5.5 и ниже больше не получают официальных обновлений безопасности, и, таким образом, лучше не использовать.)

/eМодификаторы в Regex также «зло»

Если вы работаете PHP 5.4.x или ниже, вы хотите, чтобы следить за PHP preg_replace звонки, которые заканчиваются с e. Это может выглядеть следующим:

$html = preg_replace(
    '((.*?)>)e',
    '"" . strtoupper("") . ">"',
    $html
);)
// or
$html = preg_replace(
    '~(.*?)>~e',
    '"" . strtoupper("") . ">"',
    $html
);)

PHP предлагает различные способы «забор» в вашем регулярном выражении, но основное, что вы хотите быть начеку является «е», как последний символ первого аргумента preg_replace . Если он есть, вы на самом деле прохождения весь найденный сегмент в качестве аргумента в ваш рядный PHP, а затем eval ING его. Это имеет точно такие же вопросы, как eval если бы вы позволяете пользователь-вход идти в вашу функцию. Пример кода можно заменить вместо этого с помощью preg_replace_callback . Преимущество этого заключается в том, что вы выписали свою функцию, так что злоумышленнику труднее изменить то, что получает оценку. Таким образом, вы бы написать выше, как:

// uppercase headings
$html = preg_replace_callback(
    '((.*?)>)',
    function ($m) {
        return "" . strtoupper($m[2]) . "$m[1]>";
    },
    $html
);

Сдача пользователя ввода create_function s также плохо …

PHP также имеет create_function функцию. Это в настоящее время амортизированы в PHP 7.2, но это было очень похоже eval и имел те же основные недостатки: он позволяет строку (второй аргумент), который будет превращен в исполняемый PHP. И это было те же риски: это слишком легко для вас, чтобы случайно дать умный взломщик возможность делать что-либо на вашем сервере, если вы не были осторожны.

Это одно, если вы на PHP над 5.3, то даже легке для того чтобы зафиксировать чем preg_replace однако. Вы можете просто создать свою собственную функцию анонимного без использования строк в качестве посредников. Это и более безопасным и более читаемым, по крайней мере на моих глазах.

assertЯвляется также eval -как

assertэто не функция, я вижу, многие разработчики PHP использовать, в WordPress или за ее пределами. Его цель заключается в очень легком утвержденияо о предварительных условиях для вашего кода. Но он также поддерживает eval операцию типа -типа. По этой причине, вы должны быть осторожны с ним, как вы eval . Строка основе утверждений (сердце, почему это плохо) также deprecated в PHP 7.2, что означает, что она должна быть меньше беспокойства в будущем.

Включение переменных файлов является способом возможного разрешения неконтролируемого исполнения PHP

Мы очень хорошо изучили, почему eval это плохо, но что-то вроде include или require($filename'.php') может, особенно там, где $filename устанавливается из пользовательского контролируемого значения, быть так же плохие новости. Причина тонко отличается от eval . Переменные имена файлов часто используются для таких вещей, как простой URL-файл для разгрома в приложениях, не входящих в WordPress PHP. Но вы можете увидеть их, используемых в WordPress, а также.

Суть проблемы, что, когда вы include require include_once (или) вы делаете ваш require_once скрипт выполнить включен файл. Это, более или менее, концептуально eval ING, что файл, хотя мы редко думаем об этом таким образом.

Если вы написали все файлы, которые include может вытащить переменная, и рассмотрели, что произойдет, когда это произойдет, вы в порядке. Но это плохая новость, если вы не рассмотрели то, что include ING password.php или будет wp-config.php делать. Это также плохая новость, если кто-то может добавить вредоносный файл, а затем выполнить ваш include (хотя в этот момент вы, вероятно, имеют большие проблемы).

Решение этого не слишком трудно, хотя: жесткий код включает в себя, когда вы можете. Если вы не можете, иметь либо белый список (лучше) или черный список файлов, которые могут быть включены. Если файлы в белом списке (то есть: вы проверили, что он делает при добавлении), вы будете знать, что вы в безопасности. Если его нет в вашем белом списке, ваш скрипт не будет включать его. С этой простой настройки, вы довольно безопасно. Белый список будет выглядеть примерно так:

$white_list = [‘db.php’, filter.php’, ‘condense.php’]
If (in_array($white_list, $file_to_include)) {
include($file_to_include);
}

Никогда не передавайте пользовательский вход shell_exec и варианты

Это большой. shell_exec, system exec , и backticks в PHP все позволяют код, который вы работаете, чтобы поговорить с основной (обычно Unix) оболочки. Это похоже на то, что делает eval опасным, но в два раза. Удвоено, потому что если вы позволяете пользователю ввода через здесь небрежно, злоумышленник даже не связан ограничениями PHP.

Возможность запуска команд оболочки phP может быть очень полезной в качестве разработчика. Но если вы когда-нибудь позволить пользователь вход там, они имеют возможность тайно получить много опасных полномочий. Так что я бы пойти так далеко, чтобы сказать, что пользовательский вход никогда не должны быть переданы shell_exec функции типа.

Лучший способ, который я мог бы думать, чтобы справиться с такого рода ситуации, если у вас было искушение реализовать его, было бы предоставить пользователям доступ к небольшой набор известных-безопасных предопределенных команд оболочки. Это можно было бы обеспечить. Но даже тогда я предупреждаю вас быть очень осторожными.

Смотреть для unserialize ; Он запускает код автоматически

Основное действие вызова serialize на живой объект PHP, хранение этих данных где-то, а затем с помощью этого сохраненного значения позже, unserialize чтобы этот объект обратно к жизни прохладно. Это также достаточно часто, но это может быть рискованно. Почему рискованно? Если вход в этот unserialize вызов не является полностью безопасным (скажем, он хранится как файл cookie, а не в базе данных…), злоумышленник может изменить внутреннее состояние объекта таким образом, чтобы unserialize заставить вызов сделать что-то плохое.

Этот подвиг является более эзотерическим и менее вероятно, будет замечен, чем eval вопрос. Но если вы используете файл cookie в качестве механизма хранения серийных данных, не используйте serialize эти данные. Используйте что-то вроде json_encode и json_decode . С этими двумя PHP никогда не будет автоматически выполнять любой код.

Основная уязвимость здесь заключается в том, что, когда PHP unserialize s строку в класс, он называет магический __wakeup метод на этом классе. Если допускается непроверенный пользовательский unserialized вход, то что-то вроде вызова базы данных или удаления файлов в __wakeup методе потенциально может быть направлено на опасное или нежелательное место.

unserializeотличается от eval уязвимостей, поскольку требует использования магических методов на объектах. Вместо того, чтобы создавать свой собственный код, злоумышленник вынужден злоупотреблять уже написанными методами на объекте. И __destruct __toString магические методы на объектах также являются рискованными, как это oWASP Вики страница объясняет.

В общем, вы в порядке, если вы не используете __wakeup __destruct , или __toString методы в ваших классах. Но поскольку позже вы можете увидеть, что кто-то добавит их в класс, это хорошая идея, чтобы никогда не позволять пользователю рядом с вашими звонками serialize и unserialize передавать все общедоступные данные для такого использования, хотя что-то вроде JSON json_encode json_decode (и) где никогда не бывает автоматического выполнения кода.

Получение URL-адресов с file_get_contents рискованным

Распространенная практика при быстром написании некоторых КОД PHP, который должен вызвать внешний URL, заключается в том, чтобы file_get_contents достичь. Это быстро, это легко, но это не супер безопасно.

Проблема с file_get_contents тонким, но это достаточно часто, что хосты иногда настроить PHP даже не позволяют получить доступ к внешним URL-адресам. Это должно защитить тебя.

Проблема здесь заключается в том, что file_get_contents будет получать удаленные страницы для вас. Но когда он делает это, он не проверяет целостность соединения протокола HTTPS. Это означает, что ваш сценарий потенциально может стать жертвой атаки «человек в середине», которая позволит злоумышленнику вложить в результат вашей страницы практически все, что он file_get_contents хочет.

Это более эзотерическая атака. Но для защиты от него, когда я пишу современный (композитор основе) PHP, я почти всегда использую Guzzle обернуть более безопасной CURL API. В WordPress, это еще проще: использовать wp_remote_get . Он работает гораздо более последовательно, чем file_get_contents , и это будет по умолчанию для проверки SSL соединений. (Вы можете переключить, что покинуть, но, гм, может быть, не …) А еще лучше, но немного больше wp_safe_remote_get раздражает говорить о, есть и т.д. Они работают одинаково, чем функции без safe_ их имени, но они будут убедиться, что небезопасные перенаправления и препровождения не произойдет на этом пути.

Не доверяйте слеповали URL-адрес отfilter_var

Так что это один немного неясным, так реквизит Для Криса Вейгмана для объяснения его в этом WordCamp говорить. В целом, PHP filter_var является отличным способом для проверки или дезинфекции данных. (Хотя, не путайте, о которых вы пытаетесь сделать …)

Проблема здесь довольно конкретна: если вы пытаетесь использовать ее для обеспечения безопасности URL-адреса, filter_var не проверяется протокол. Это не часто проблема, но если вы проходите пользовательский вход в этот метод для проверки, и используют FILTER_VALIDATE_URL , что-то вроде javascript://comment%0aalert(1) будет пройти. То есть, это может быть очень хорошим вектором для основной атаки XSS в месте, которое вы не ожидаете.

Для проверки URL-адреса функция WordPress esc_url будет иметь аналогичное воздействие, но пропускает только разрешенные протоколы. javascript Однако, в отличие filter_var от, он вернет пустую строку (не ложную) для запрещенного протокола, который передается ей.

WordPress-специфические функции, чтобы держать глаз на

В дополнение к основной PHP потенциально уязвимых функций, Есть некоторые WordPress конкретных функций, которые могут быть немного gotcha. Некоторые из них очень похожи на различные опасные функции, перечисленные выше, некоторые немного отличаются.

WordPress Unserializes сmaybe_unserialize

Это одно вероятно очевидно если вы читаете выше. В WordPress есть функция называется maybe_unserialize и, как вы догадались, он unserializes то, что прошло к нему, если это необходимо.

Там нет какой-либо новой уязвимости, что это вводит, проблема заключается в том, что так же, как основная unserialize функция, это может привести к уязвимому объекту, который будет использоваться, когда он unserialized.

is_adminНе отвечает, если пользователь является администратором!

Это один довольно простой, но функция неоднозначна по названию, и поэтому он склонен путать людей или быть пропущены, если вы в спешке. Вы всегда должны проверить, что пользователь, который пытается выполнить действие в WordPress имеет права и привилегии, необходимые для выполнения этого действия. Для этого следует использовать эту current_user_can функцию.

Но вы можете, ошибочно, думаю, что is_admin будет сказать, если вы текущий пользователь является администратором уровня учетной записи и, таким образом, должны быть в состоянии установить опцию плагин использует. Это ошибка. Что is_admin делает в WordPress вместо говорю вам, если текущая загрузка страницы находится на административной стороне сайта (против передней стороны). Таким образом, каждый пользователь, который может получить доступ к странице администрирования (например, «Dashboard») сможет потенциально пройти эту проверку. До тех пор, как вы is_admin помните, что о типе страницы, а не текущего пользователя, вы будете в порядке.

add_query_arg()Не дезинфицировать URL-адреса

Это не так часто, но была большая волна обновлений в экосистеме WordPress несколько лет назад, потому что публичная документация по этим функциям не была правильной. Основная проблема заключается в том, что add_query_arg функция (и ее обратная) remove_query_arg не автоматически дезинфицировать URL-адрес сайта, если URL не был передан ему, и люди думали, что он сделал. Многие плагины были введены в заблуждение Кодексом, и в результате использовали это небезопасно.

Основное, что они должны были сделать по-другому: дезинфицировать результат вызова к этой функции, прежде чем использовать его. Если вы сделаете это, вы действительно в безопасности от XSS атак, что вы думали, что они были. Так что это выглядит примерно так:

echo esc_url( add_query_arg( 'foo', 'bar' ) );

$wpdb->query()Открыт для атаки на инъекцию СЗЛ

Если вы знаете о инъекциях S’L,это может показаться глупым, даже лишним для списка. Потому что дело в том, что любой способ получить доступ к базе данных (скажем, с помощью драйверов базы данных PHP mysqli или PDO) для создания запросов базы данных, которые позволяют для атак инъекций S’L.

Причина, по которой я специально призывая $wpdb->query в том, что некоторые другие методы (например, insert и delete т.д.) на $wpdb заботиться о инъекционных атак для вас. Кроме того, если вы привыкли к созданию основных запросов базы данных WordPress WP_Query с или аналогичными, вам не нужно будет рассматривать инъекцию S’L. Вот почему я призываю его: чтобы убедиться, что вы понимаете, инъекционные атаки на базу данных возможно, когда вы впервые попытаетесь использовать, $wpdb чтобы сделать свой собственный запрос.

Что делать? Используйте, $wpdb->prepare() а затем $wpdb->query() . Вы также хотите, чтобы убедиться, что вы готовите перед другими «получить» $wpdb методы, get_row() как, и get_var() . В противном случае Бобби таблицы могут получить вас.

esc_sqlНе защищает вас от инъекций S’L либо

Для большинства разработчиков WordPress, я бы сказал, что esc_sql не регистрируется с какой-либо смысл, но он должен. Ase мы только что упомянули, вы должны wpdb->prepare() использовать, прежде чем сделать какой-либо запрос базы данных. Это будет держать вас в безопасности. Но это заманчиво и понятно, что разработчик может достичь esc_sql вместо этого. И они могут ожидать, что это будет безопасно.

Проблема заключается esc_sql в том, что не имеет как надежные средства защиты от инъекций S’L. Это действительно прославленная версия add_slashes функции PHP,которую вы не рекомендуется использовать для защиты вашей базы данных в течение многих лет.

Там еще многое сделать, но это большой старт

Безопасность может быть намного больше, чем просто поиск функций в коде, которые злоумышленники могут неправильно использовать. Мы, например, не обсуждали, например, необходимость проверки и дезинфекции всех данных, которые вы получаете от пользователей и избежать его, прежде чем положить его на веб-страницу (хотя я недавно опубликовать статью на эту тему, «Защита Вашего WordPress сайта против Кросс-сайт Сценарий атаки«). Но вы можете и должны использовать это как часть более широкой стратегии безопасности.

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

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

Источник: smashingmagazine.com

Великолепный Журнал

Великолепный, сокрушительный, разящий (см. перевод smashing) независимый журнал о веб-разработке. Основан в 2006 году в Германии. Имеет няшный дизайн и кучу крутых авторов, которых читают 2 млн человек в месяц.

Добавить комментарий

%d такие блоггеры, как: