Мне передали отчет об уязвимости (1), который, по-видимому, подразумевает, что может быть проблема безопасности в том, как Wordpress обрабатывает URL-адреса со следующими тильдами. Кажется, сканер считает, что веб-сайт может обслуживать некоторые списки каталогов и тому подобное.
Я был удивлен тем, что мой веб-сайт по-прежнему размещал контент по этим различным URL-адресам, поэтому я провел тест, установив полностью пустой экземпляр WP, переключившись на постоянные ссылки «Опубликовать имя», и подтвердил, что да, любой URL-адрес с добавленной тильдой по-прежнему интерпретируется как URL без тильды.
Действительно, URL-адрес, как это:
https://mywordpresssite.com/my-permalink
Также доступен со следующими URL:
https://mywordpresssite.com/my-permalink~
https://mywordpresssite.com/my-permalink~/
https://mywordpresssite.com/my-permalink~~~~~~
Я немного покопался, чтобы увидеть, где WP анализирует постоянные ссылки, и отследил это class-wp.php
в parse_request
методе, но не смог продвинуться дальше.
Мой вопрос заключается в том, предназначено ли это поведение для WP, и если да, то есть ли способ отключить его, чтобы тильды не совпадали? Зачем WP интерпретировать URL-адреса с тильдами как URL-адреса без них?
(1) Да, теперь мы все видели пару крупных взломов и утечек данных в Великобритании, это то время, когда ребята из «службы безопасности» делают вид, что делают свое дело, передавая нам разработчики отчеты о сканировании на 200 страниц полный ложных срабатываний и общих проблем, о которых они ничего не знают, ожидая, что если мы прочтем и выполним этот доклад, ничего плохого не произойдет.
источник
sanitize_title
, но так как он фильтруется, невозможно написать всегда верное решение. Так что я пошел конкретно.Да, как уже объяснялось,
WP_Query::get_posts()
используетsanitize_title_for_query()
( который используетsanitize_title()
) для очистки названия поста единственного поста.Короче, после того, как название поста прошло
sanitize_title_for_query()
, такmy-permalink === my-permalink~~~
какsanitize_title_for_query()
убирает трейлинг~~~
. Вы можете проверить это, выполнив следующие действия:Это не то, что вы можете отключить. В
sanitize_title()
вызванном фильтре есть фильтр,sanitize_title
который вы можете использовать для изменения поведенияsanitize_title()
, но это почти всегда не очень хорошая идея. SQL-инъекция очень серьезна, поэтому, если что-то проскользнет из-за плохой санитарии, это может серьезно повлиять на целостность вашего сайта. «Из-за санитарии» иногда может быть боль в заднице.Я не уверен, что вы после этого, но я подозреваю, что вы, возможно, хотите 404 отдельных сообщений с этим тильда, по вашим словам, "выключить его". На этом этапе я могу думать только о том, чтобы остановить основной запрос, когда у нас есть эти тильды. Для этого мы можем отфильтровать
posts_where
предложение основного запроса.ФИЛЬТР
Примечание: я рассматривал только обычные отдельные сообщения, а не статические первые страницы или вложения, вы можете расширить фильтр, чтобы включить это
Несколько замечаний
Приведенный выше фильтр вернет страницу 404, когда у нас будет такой URL
https://mywordpresssite.com/my-permalink~~~~~~
. Однако, удаливremove_action( 'template_redirect', 'redirect_canonical' );
из фильтра, можно автоматически перенаправить запросhttps://mywordpresssite.com/my-permalink
и отобразить один пост, благодаряredirect_canonical()
которому подключается тот,template_redirect
который обрабатывает перенаправление WordPress, созданного 404-ми.источник
Да, кажется странным, что у нас должно быть одинаковое совпадение для:
и, например,
Почему это возможно, кажется, эта часть из
WP_Query::get_posts()
метода:где
sanitize_title_for_query()
определяется как:Должна быть возможность сделать это более строгим с помощью
sanitize_title
фильтра, но не стоит переопределять вывод по умолчанию, основанный на томsanitize_title_with_dashes
, что отвечает за санитарию здесь. Вам следует подумать о создании заявки, а не об ее изменении, если об этом поведении уже не было ни одного тока.Обновить
Интересно, могли бы мы очистить шум от текущего пути
sanitize_title_for_query()
и перенаправить на очищенный URL при необходимости?Вот демоверсия, с которой вы можете поиграть на своем тестовом сайте и настроить ее под свои нужды:
Возможно, даже лучше использовать
sanitize_title_with_dashes()
напрямую, чтобы избежать фильтров и заменить:с:
PS: я думаю, что я изучил этот трюк, чтобы получить текущий путь с пустым
add_query_arg( [] )
, из @gmazzap ;-) Это также отмечено в Кодексе. Еще раз спасибо @gmazzap за напоминание об использованииesc_url()
при отображении выводаadd_query_arg( [] )
или,esc_url_raw()
например, при перенаправлении его. Проверьте предыдущую ссылку на Кодекс для этого тоже.источник
add_query_arg
нужно избегатьesc_url
илиesc_url_raw
предотвращать проблемы безопасности ...Позвольте мне объяснить обработку запроса в WordPress и метод изменения поведения WordPress для достижения ваших целей.
Разбор запроса
Когда WordPress получает запрос, он начинает процесс разбора запроса и преобразования его в страницу. Ядро этого процесса начинается, когда
WP::main()
вызывается основной метод запроса WordPress . Эта функция анализирует запрос, как вы правильно определили, вparse_request()
(inincludes/class-wp.php
). Там WordPress пытается сопоставить URL с одним из правил перезаписи . Когда URL-адрес совпадает, он создает строку запроса из частей URL-адреса и кодирует эти части (все между двумя слешами)urlencode()
, чтобы предотвратить использование специальных символов, таких как&
путаница в строке запроса. Эти закодированные символы могли заставить вас думать, что проблема заключалась в этом, но они фактически превращаются в соответствующие им «настоящие» символы при разборе строки запроса.Выполнение запроса, связанного с запросом
После того, как WordPress проанализировал URL-адрес, он устанавливает основной класс запросов
WP_Query
, что делается в том жеmain()
методеWP
класса. ОсновуWP_Query
можно найти в егоget_posts()
методе, где все аргументы запроса анализируются и обрабатываются, а фактический запрос SQL создается (и, в конце концов, запускается).В этом методе в строке 2730 выполняется следующий код:
Это очищает сообщение для его извлечения из таблицы сообщений. Вывод отладочной информации внутри цикла показывает, что именно в этом заключается проблема: имя вашего сообщения
my-permalink~
, преобразуется вmy-permalink
, которое затем используется для извлечения сообщения из базы данных.Функция очистки заголовка поста
Функция
sanitize_title_for_query
вызываетсяsanitize_title
с правильными параметрами, после чего происходит санация заголовка. Теперь ядро этой функции применяетsanitize_title
фильтр:Этот фильтр, в родном WordPress, одна функция прилагается к нему:
sanitize_title_with_dashes
. Я написал обширный обзор того, что делает эта функция, который можно найти здесь . В этой функции строка, вызывающая вашу проблемуЭта строка удаляет все символы, кроме буквенно-цифровых символов, пробелов, дефисов и подчеркиваний.
Решение вашей проблемы
Таким образом, существует в основном единственный способ решить вашу проблему: удалить
sanitize_title_with_dashes
функцию из фильтра и заменить ее собственной функцией. На самом деле это не так сложно сделать, но :Самое главное : WordPress использует результат
sanitize_title
функции непосредственно в запросе SQL по следующей строке:Если вы когда-нибудь захотите изменить фильтр, убедитесь, что вы правильно экранировали заголовок, прежде чем он будет использован в запросе!
Вывод: решение вашей проблемы не является необходимым в плане безопасности, но если вы хотите это сделать, замените его
sanitize_title_with_dashes
собственной функциональностью и обратите внимание на экранирование SQL.Примечание: все имена файлов и номера строк соответствуют файлам WordPress 4.4.2.
источник
Некоторые люди уже объяснили проблему, поэтому я просто опубликую альтернативное решение. Должно быть довольно очевидным.
Вы должны сделать что - то немного по- другому для иерархических типов почтовых , хотя, так как
WP_Query
будет проходитьpagename
через ,wp_basename
а затем дезинфицировать его, такquery_vars['pagename']
иget_query_var('pagename')
не будет соответствовать для детей becuase последний не будет содержать родительскую часть.Я хотел бы
redirect_canonical
просто позаботиться об этом дерьме.источник
ЭТО ИСПРАВЛЕНИЕ ... ДЛЯ УСТРАНЕНИЯ WORDPRESS ПРОСТО ДОБАВЬТЕ НАЧАЛО БЕЗОПАСНОГО мода, установленного над блоком, сгенерированным Wordpress.
источник
Вы всегда можете попробовать добавить следующее в ваш
.htaccess
файл:Вторая строка выше должна идти прямо под первой показанной строкой. Это должно препятствовать
index.php~
отображению в URL.источник