• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Техника полуавтоматического обнаружения новых уязвимостей в плагинах WordPress.

вавилонец

CPU register
Пользователь
Регистрация
17.06.2021
Сообщения
1 116
Реакции
1 265
ОРИГИНАЛЬНАЯ СТАТЬЯ
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 на SSD для Jolah Molivski ---> 0x5B1f2Ac9cF5616D9d7F1819d1519912e85eb5C09 для поднятия ноды ETHEREUM и тестов

Обновление (2022-02-26): инструмент стал общедоступным: https://github.com/kazet/wpgarlic.
Плагины WordPress открывают ряд интерфейсов, таких как:

  1. конечные точки AJAX (/wp-admin/admin-ajax.php)
  2. Страницы меню администратора (/wp-admin/admin.php?page=...)
  3. PHP-файлы (в каталоге /wp-content/plugins/),
  4. REST-маршруты (/wp-json/...).

Эти интерфейсы имеют согласованную границу доверия: мы знаем, куда идет недоверенный вход, и можем определить, какие операции выполняются на этом входе.

Например, если вы посещаете страницу с .php кодом , предоставляете соответствующие параметры и вызываете удаление файла, вы знаете, что это уязвимость. Вы знаете, какие параметры вы контролируете, а какие нет - например, вы можете перенаправить вошедшего в систему администратора на страницу меню администратора с произвольными GET-параметрами, но вы не контролируете его cookies.
Поэтому возможно полуавтоматическое сканирование на наличие нескольких классов уязвимостей во всех плагинах WordPress.
Я написал инструмент, который:

  • выполняет каждую конечную точку AJAX, страницу меню, маршрут REST или файл несколько раз,
  • внедряет полезную нагрузку в массивы GET, POST и т.д. или параметры REST (подробнее о том, как это делается, в следующем разделе),
  • анализирует выходные данные с помощью уродливой кучи регулярных выражений1 , чтобы обнаружить
    • вызовы функций WordPress (таких как wp_delete_post),
    • сбои ("No such file or directory", "You have an error in your SQL syntax", ...),
    • XSS (передача известной полезной нагрузки, содержащей " или <),
    • и т.д.

Этот метод можно перенести на другие экосистемы плагинов CMS, но не напрямую, например, на пакеты Python. Если пакет Python позволяет удалять произвольные файлы, это может быть или не быть уязвимостью в зависимости от роли пакета и вашей конкретной установки.
Инъекция параметров
В PHP массивы _GET, _POST, _SERVER, _COOKIE и _REQUEST содержат различные параметры запроса (например, данные GET и POST, cookies, конфигурацию сервера и заголовки). Я заменил их на объекты-макеты, которые позволяют получить доступ к любому ключу - и с определенной вероятностью возвращают полезную нагрузку из предопределенного списка полезной нагрузки.

Простой имитатор массива $_POST можно создать с помощью следующего кода:

Код:
<?php

class Mock implements ArrayAccess {
    function offsetGet($offset) {
        return "payload";
    }

    function offsetExists($offset) {
        return true;
    }

    function offsetSet($offset, $value) { }

    function offsetUnset($offset) { }
}

$_POST = new Mock();

echo $_POST["parameter_name"];

В приведенном выше фрагменте будет выведена полезная нагрузка.
Предположим, что массив $_REQUEST был подделан способом, аналогичным описанному выше, и что AJAX-маршрут обрабатывается следующей функцией:

Код:
public function delete_saved_block() {
    $block_id = (int) sanitize_text_field($_REQUEST['block_id']);
    $deleted_block = wp_delete_post($block_id);
    wp_send_json_success($deleted_block);
}

При обращении к $_REQUEST['block_id'] mock вернет полезную нагрузку, что позволит определить, что wp_delete_post был вызван на контролируемом злоумышленником значении.
Такой подход позволял легко внедрять полезную нагрузку, даже если имя параметра было трудно угадать - инструмент не различал id и secret_parameter_65e3c14a1d.
Некоторые ключи нужно было исключить вручную (например, $_SERVER['HTTP_AUTHORIZATION'] или $_GET['doing_wp_cron']), поскольку их значения обрабатывались WordPress, и их предоставление приводило к тому, что код плагина не был доступен.
Кроме того, с некоторой вероятностью вместо строковой полезной нагрузки возвращался массив случайного типа:

  • одноэлементный массив со строковой полезной нагрузкой,
  • рекурсивно, объект, позволяющий получить доступ к любому ключу,
  • одноэлементный массив: случайная полезная нагрузка → случайная полезная нагрузка.

Обнаружение уязвимостей

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

XSS

Для обнаружения XSS были реализованы проверки, обнаруживающие, что полезная нагрузка возвращается эхом (или возвращается с экранированием, которое не предотвращает XSS, например, префикс " с \).

СБОИ

Были обнаружены следующие типы сбоев:

  • fopen() / file_get_contents() / require() / require_once() / include() / include_once() ошибки и сообщения об ошибках "No such file or directory" или "failed to open stream",
  • сообщения об ошибках unlink(),
  • сбои, связанные с call_user_func(),
  • сообщения об ошибках SQL,
  • ошибки unserialize(),
  • ошибки разбора / синтаксиса для обнаружения вызовов eval(),
  • сообщение об ошибке "команда не найдена",
  • сообщения об ошибках simplexml_load_string()2.
Утечки информации

Выходные данные анализировались на предмет отображения известных электронных адресов пользователей или имен файлов.

Операции WordPress

WordPress был проанализирован для обнаружения:

  • вызовы maybe_unserialize,
  • вызовы update_option/update_site_option/delete_option,
  • вызовы wp_insert_user,
  • вызовы wp_insert_post/wp_update_post/wp_delete_post,
  • вызовы wp_mail,
  • вызовы query (этот вызов дал особенно много ложных срабатываний, которые потребовали дополнительной фильтрации),
  • вызовы get_users (этот вызов был добавлен после случайного обнаружения CVE-2021-25110, где злоумышленник может слить произвольные сообщения электронной почты пользователя через созданный поисковый запрос пользователя).

Дополнительные проверки
После фаззинга панель администратора, главная страница и страницы постов были просмотрены на предмет обнаружения вхождений известных полезных нагрузок. Это позволило, например, обнаружить CVE-2021-24975 в social-networks-auto-poster-facebook-twitter-g.

Обновление (2022-02-26): кроме того, любые попытки доступа к загруженным файлам записываются в журнал, чтобы их можно было проверить вручную.
Изменения в PHP
Я исправил PHP так, чтобы сравнение равенства между любым значением и известной полезной нагрузкой возвращало true с вероятностью 1/3. С помощью этого патча я смог обнаружить:

Код:
if ($_GET['action'] == 'please-remove-post') {
    wp_delete_post($_GET['id']);
}

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

Код:
if (in_array($order, array("ASC", "DESC"), true)) {
    query("(...) ORDER BY $order");
}

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

Другие изменения

Кроме того, я исправил интерпретатор PHP таким образом:

  • При выполнении base64_decode для известной полезной нагрузки, эта полезная нагрузка возвращалась снова,
  • Когда json_decode выполнялся над известной полезной нагрузкой, возвращался объект, который возвращал полезную нагрузку при обращении к любому ключу. Это были те же объекты, которые служили, например, массивами $_GET,
  • когда выполнялось перенаправление, отображалась соответствующая информация, чтобы можно было обнаружить уязвимости Open Redirect.

Тестирование

При разработке критически важным был подход, основанный на тестировании. Тесты проверяли, что инструмент найдет известную уязвимость. Например, я могу написать тест для проверки того, что при проверке конечной точки wp_ajax_heateor_sss_import_config плагина sassy-social-share версии 3.3.23 инструмент должен обнаружить, что maybe_unserialize() вызывается на управляемой злоумышленником полезной нагрузке. Этот подход привел к большому количеству ложных срабатываний. Это было преднамеренное решение, поскольку я хотел отсортировать множество отчетов, а не пропустить уязвимости. Может быть написание дополнительной логики фильтрации. Например, было несколько отчетов, в которых HTML полезная нагрузка возвращалась эхом - но при их проверке я заметил, что добавляется правильный JSON Content-Type заголовок. Это был один из случаев, которые можно было бы проверять автоматически. Фаззинг проводился внутри контейнеров Docker, созданных заново для каждого плагина. Было важно отключить сеть, потому что многие плагины вызывают другие веб-сервисы, и я хотел избежать отправки туда случайных полезных нагрузок. Мне также показалось полезным разделить проверку плагинов и анализ выходных данных. Поскольку выходные данные анализировались с помощью множества регулярных выражений, возникали ошибки. Поэтому относительно быстрое повторное сканирование позволяло ускорить разработку. Сканирование тысяч плагинов было бы невозможно без автоматизации работы. К счастью, плагины WordPress используют согласованные интерфейсы для интеграции с WordPress, например:
  • все REST-маршруты собираются в центральном реестре, доступном через: rest_get_server()->get_routes(),
  • действия AJAX создаются путем добавления хука с именем, начинающимся с wp_ajax_,
  • существует один реестр со всеми страницами меню администратора.
Поэтому все маршруты REST, действия AJAX и действия меню могут быть перечислены одинаково, независимо от того, какой плагин сканируется. Конечно, все PHP-файлы также могут быть легко перечислены. Все плагины могут быть установлены одинаково: Я использовал WP-CLI - инструмент, позволяющий установить, активировать, деактивировать или удалить плагин из командной строки. Список плагинов можно было автоматически загрузить из API реестра плагинов WordPress.
Все вышеперечисленные приемы позволили создать инструмент, не требующий специфического для плагинов кода.
Из-за нехватки времени я сосредоточился только на самых популярных плагинах. На данный момент следующие ошибки, найденные инструментом, уже исправлены и опубликованы:


IDPluginCVENumber of active installationsTypeLink
1woocommerceCVE-2022-07755,000,000Arbitrary comment deletionWPScan
2updraftplusCVE-2021-250223,000,000Reflected XSSWPScan
3code-snippetsCVE-2021-25008500,000Reflected XSSWPScan
4woocommerce-pdf-invoices-packing-slipsCVE-2021-24991300,000Reflected XSSWPScan
5ad-inserterCVE-2022-0288200,000Reflected XSSWPScan
6caldera-formsCVE-2022-0879200,000Reflected XSSWPScan
7complianz-gdprCVE-2022-0193200,000Reflected XSSWPScan
8custom-facebook-feedCVE-2021-25065200,000Reflected XSSWPScan
9favicon-by-realfavicongeneratorCVE-2022-0471200,000Reflected XSSWPScan
10loginpressCVE-2022-0347200,000Reflected XSSWPScan
11popup-builderCVE-2022-0479200,000Reflected XSSWPScan
12use-any-fontCVE-2021-24977200,000Arbitrary CSS append + stored XSSWPScan
13white-label-cmsCVE-2022-0422200,000Reflected XSSWPScan
14wp-cerberCVE-2022-0429200,000Stored XSSWPScan
15wp-gdpr-complianceCVE-2022-0147200,000Reflected XSSWPScan
16capability-manager-enhancedCVE-2021-25032100,000Arbitrary settings updateWPScan
17chatyCVE-2021-25016100,000Reflected XSSWPScan
18cmp-coming-soon-maintenanceCVE-2022-0188100,000Possibility to add arbitrary CSSWPScan
19download-managerCVE-2021-24969100,000Stored XSSWPScan
20download-managerCVE-2021-25069100,000Reflected XSSWPScan
21email-subscribersCVE-2022-0439100,000Blind SQL InjectionWPScan
22learnpressCVE-2022-0271100,000Reflected XSSWPScan
23menu-imageCVE-2022-0450100,000Stored XSSWPScan
24modern-events-calendar-liteCVE-2021-24925100,000Reflected XSSWPScan
25modern-events-calendar-liteCVE-2021-24946100,000Blind SQL injectionWPScan
26modern-events-calendar-liteCVE-2021-25046100,000Stored XSSWPScan
27paid-memberships-proCVE-2021-25114100,000Blind SQL InjectionWPScan
28squirrly-seoCVE-2021-25019100,000Reflected XSSWPScan
29ti-woocommerce-wishlistCVE-2022-0412100,000Blind SQL InjectionWPScan
30webp-converter-for-mediaCVE-2021-25074100,000Open redirectWPScan
31woocommerce-products-filterCVE-2021-25085100,000Reflected XSSWPScan
32wpvivid-backuprestoreCVE-2021-24994100,000Stored XSSWPScan
33wpvivid-backuprestoreCVE-2022-0531100,000Reflected XSSWPScan
34advanced-cf7-dbCVE-2021-2490590,000Arbitrary file removalWPScan
35kingcomposerCVE-2021-2504890,000Stored XSSWPScan
36kingcomposerCVE-2022-016590,000Open redirectWPScan
37social-networks-auto-poster-facebook-twitter-gCVE-2021-2497590,000Stored XSSWPScan
38social-networks-auto-poster-facebook-twitter-gCVE-2021-2507290,000CSRF post removalWPScan
39themify-portfolio-postCVE-2022-020080,000Reflected XSS (logged-in POST 3)WPScan
40woo-product-feed-proCVE-2021-2497480,000Stored XSSWPScan
41woo-product-feed-proCVE-2022-042680,000Reflected XSS (logged-in POST 3)WPScan
42www-xml-sitemap-generator-orgCVE-2022-034670,000Reflected XSS and RCEWPScan
43bookingCVE-2021-2504060,000Reflected XSSWPScan
44interactive-3d-flipbook-powered-physics-engineCVE-2022-042360,000Stored XSSWPScan
45mappress-google-maps-for-wordpressCVE-2022-020860,000Reflected XSSWPScan
46permalink-managerCVE-2022-020160,000Reflected XSSWPScan
47post-gridCVE-2022-044760,000Reflected XSS (logged-in POST 3)WPScan
48powerpack-lite-for-elementorCVE-2021-2502760,000Reflected XSSWPScan
49real-cookie-bannerCVE-2022-044560,000CSRF settings reset and deleting all GDPR consentsWPScan
50wd-instagram-feedCVE-2021-2504760,000Reflected XSSWPScan
51woocommerce-currency-switcherCVE-2021-2504360,000Reflected XSSWPScan
52woocommerce-currency-switcherCVE-2022-023460,000Reflected XSSWPScan
53wp-responsive-menuCVE-2021-2497160,000Stored XSSWPScan
54wp-rss-aggregatorCVE-2021-2498860,000Stored XSSWPScan
55wp-rss-aggregatorCVE-2022-018960,000Reflected XSS (logged-in POST 3)WPScan
56ditty-news-tickerCVE-2022-053350,000Reflected XSSWPScan
57event-ticketsCVE-2021-2502850,000Open redirectWPScan
58nimble-builderCVE-2022-031450,000Reflected XSSWPScan
59simple-membershipCVE-2022-032850,000CSRF member deletionWPScan
60super-socializerCVE-2021-2498750,000Reflected XSSWPScan
61bnfwCVE-2022-034540,000E-mail leakWPScan
62thirstyaffiliatesCVE-2022-039840,000Arbitrary affiliate link creationWPScan
63tutorCVE-2021-2501740,000Reflected XSSWPScan
64advanced-cron-managerCVE-2021-2508430,000Arbitrary cron configuration changeWPScan
65contact-form-7-skinsCVE-2021-2506330,000Reflected XSSWPScan
66content-eggCVE-2022-042830,000Reflected XSS (logged-in POST 3)WPScan
67easy-paypal-donationCVE-2021-2498930,000CSRF post removalWPScan
68futurio-extraCVE-2021-2511030,000E-mail leakWPScan
69google-pagespeed-insightsCVE-2022-043130,000Reflected XSS (logged-in POST 3)WPScan
70insight-coreCVE-2021-2495030,000Stored XSS + object injectionWPScan
71lead-form-builderCVE-2021-2496730,000Stored XSSWPScan
72master-addonsCVE-2022-032730,000Reflected XSSWPScan
73meks-easy-instagram-widgetCVE-2021-2495830,000Stored XSSWPScan
74my-calendarCVE-2021-2492730,000Reflected XSSWPScan
75notificationxCVE-2022-034930,000Blind SQL InjectionWPScan
76photo-galleryCVE-2022-016930,000SQL InjectionWPScan
77protect-wp-adminCVE-2021-2490630,000Disabling of plugin security featuresWPScan
78pz-linkcardCVE-2021-2501230,000Reflected XSSWPScan
79site-reviewsCVE-2021-2497330,000Stored XSSWPScan
80ultimate-faqsCVE-2021-2496830,000Possibility to add arbitrary FAQsWPScan
81video-conferencing-with-zoom-apiCVE-2022-038430,000E-mail leakWPScan
82woo-smart-wishlistCVE-2022-039730,000Reflected XSS (logged-in POST 3)WPScan
83wp-user-frontendCVE-2021-2507630,000SQL injection in admin panel leading to reflected XSSWPScan
84xcloner-backup-and-restoreCVE-2022-044430,000Resetting settings, including encryption keyWPScan
85ad-invalid-click-protectorCVE-2022-019020,000SQL injectionWPScan
86ad-invalid-click-protectorCVE-2022-019120,000CSRF ban removalWPScan
87advanced-product-labels-for-woocommerceCVE-2022-039920,000Reflected XSS (logged-in POST 3)WPScan
88asgaros-forumCVE-2022-041120,000Blind SQL InjectionWPScan
89bwp-google-xml-sitemapsCVE-2022-023020,000Stored XSSWPScan
90crazy-boneCVE-2022-038520,000Stored XSSWPScan
91event-calendar-wdCVE-2021-2502420,000XSSWPScan
92event-calendar-wdCVE-2021-2502520,000Possibility to add arbitrary eventsWPScan
93float-menuCVE-2022-031320,000CSRF menu deletionWPScan
94gmap-embedCVE-2021-2501120,000Arbitrary post removal, plugin settings updateWPScan
95gmap-embedCVE-2021-2508120,000Arbitrary post removal, plugin settings update via CSRFWPScan
96image-hover-effects-ultimateCVE-2021-2503120,000Reflected XSSWPScan
97material-design-for-contact-form-7CVE-2022-040420,000DoSWPScan
98miniorange-2-factor-authenticationCVE-2022-022920,000DoSWPScan
99mycredCVE-2021-2501520,000Reflected XSSWPScan
100mycredCVE-2022-028720,000E-mail leakWPScan
101mycredCVE-2022-036320,000Arbitrary post creationWPScan
102mystickyelementsCVE-2022-014820,000Reflected XSSWPScan
103navz-photo-galleryCVE-2021-2490920,000Reflected XSSWPScan
104newstatpressCVE-2022-020620,000Reflected XSSWPScan
105page-views-countCVE-2022-043420,000SQL injectionWPScan
106restaurant-reservationsCVE-2021-2496520,000Stored XSSWPScan
107woocommerce-product-addonCVE-2021-2501820,000Stored XSSWPScan
108wp-accessiblity-helperCVE-2022-015020,000Reflected XSSWPScan
109wp-stats-managerCVE-2021-2475020,000SQL injectionWPScan
110wp-stats-managerCVE-2021-2504220,000Stored XSSWPScan
111wp-stats-managerCVE-2022-041020,000Blind SQL InjectionWPScan
112wplegalpagesCVE-2021-2510620,000Stored XSSWPScan
113advanced-page-visit-counterCVE-2021-2495710,000Blind SQL injectionWPScan
114advanced-page-visit-counterCVE-2021-2508610,000Stored XSSWPScan
115affiliates-managerCVE-2021-2507810,000Stored XSSWPScan
116akismet-privacy-policiesCVE-2021-2507110,000Reflected XSSWPScan
117ari-fancy-lightboxCVE-2022-016110,000Reflected XSSWPScan
118business-profileCVE-2021-2506010,000Stored XSSWPScan
119coming-soon-pageCVE-2022-016410,000Sending any e-mail to all subscribersWPScan
120coming-soon-pageCVE-2022-019910,000Sending any e-mail to all subscribers via CSRFWPScan
121dropdown-menu-widgetCVE-2021-2511310,000Stored XSSWPScan
122duplicate-page-or-postCVE-2021-2507510,000Stored XSSWPScan
123easy-pricing-tablesCVE-2021-2509810,000CSRF post removalWPScan
124english-wp-adminCVE-2021-2511110,000Open redirectWPScan
125ibtana-visual-editorCVE-2021-2501410,000Stored XSSWPScan
126ip2location-country-blockerCVE-2021-2509510,000Banning arbitrary countriesWPScan
127ip2location-country-blockerCVE-2021-2509610,000Ban circumventionWPScan
128ip2location-country-blockerCVE-2021-2510810,000Banning countries via CSRFWPScan
129link-libraryCVE-2021-2509110,000Reflected XSSWPScan
130link-libraryCVE-2021-2509210,000CSRF settings resetWPScan
131link-libraryCVE-2021-2509310,000Arbitrary link removalWPScan
132modal-windowCVE-2021-2505110,000CSRF RCEWPScan
133page-builder-addCVE-2021-2506710,000Reflected XSSWPScan
134portfolio-wpCVE-2021-2509010,000Stored XSSWPScan
135powerpack-addon-for-beaver-builderCVE-2022-017610,000Reflected XSSWPScan
136qubelyCVE-2021-2501310,000Arbitrary post removalWPScan
137rearrange-woocommerce-productsCVE-2021-2492810,000SQL injectionWPScan
138registrations-for-the-events-calendarCVE-2021-2494310,000SQL injectionWPScan
139registrations-for-the-events-calendarCVE-2021-2508310,000Reflected XSSWPScan
140secure-copy-content-protectionCVE-2021-2493110,000SQL injectionWPScan
141smart-formsCVE-2022-016310,000Downloading form dataWPScan
142spider-event-calendarCVE-2022-021210,000Reflected XSSWPScan
143stopbadbotsCVE-2021-2507010,000Blind SQL injectionWPScan
144ultimate-product-catalogueCVE-2021-2499310,000Possibility to add arbitrary productsWPScan
145whmcs-bridgeCVE-2021-2511210,000Reflected XSSWPScan
146wicked-foldersCVE-2021-2491910,000SQL injectionWPScan
147woo-orders-trackingCVE-2021-2506210,000Reflected XSSWPScan
148woocommerce-exporterCVE-2022-014910,000Reflected XSSWPScan
149woocommerce-store-toolkitCVE-2021-2507710,000Reflected XSSWPScan
150wp-booking-systemCVE-2021-2506110,000Reflected XSSWPScan
151wp-coderCVE-2021-2505310,000CSRF RCEWPScan
152wp-photo-album-plusCVE-2021-2511510,000Stored XSSWPScan
153wp125CVE-2021-2507310,000CSRF ad deletionWPScan
154wpcargoCVE-2021-2500310,000RCEWPScan
155events-made-easyCVE-2021-250307,000SQL injectionWPScan
156likebtn-like-buttonCVE-2021-249457,000Sensitive data exposureWPScan
157likebtn-like-buttonCVE-2022-07457,000Arbitrary e-mail sendingWPScan
158wp-email-usersCVE-2021-249597,000SQL injection + object injectionWPScan
159responsive-vector-mapsCVE-2021-249476,000Arbitrary file readWPScan
160button-generationCVE-2021-250525,000CSRF RCEWPScan
Не все уязвимости были найдены непосредственно фаззером. Например, CVE-2021-25096 была обнаружена случайно при написании PoC для CVE-2021-25095. Для некоторых других уязвимостей предупреждения инструмента были лишь частью информации об уязвимости - например, инструмент уведомлял, что опция WordPress может быть обновлена любым пользователем - и поиск последствий (может ли это привести, например, к хранимому XSS) требовал ручной работы.

Выводы, достойные упоминания

Я не буду высмеивать какого-либо конкретного автора плагина, однако считаю, что некоторыми выводами стоит поделиться.

is_admin

Функция WordPress is_admin(), как вы уже, наверное, догадались определяет, предназначен ли текущий запрос для страницы административного интерфейса.
(с сайта https://developer.wordpress.org/reference/functions/is_admin/)

Документация также предупреждает, что она не проверяет, является ли пользователь администратором; для проверки ролей и возможностей используйте функцию current_user_can().

Как вы уже, наверное, догадались, это стало источником пары уязвимостей в виде:
Код:
if (is_admin()) {
    /* опасное действие */
}

URL-адреса REST-маршрутов

Рассмотрим следующий код:
Код:
register_rest_route((...), '/(...)/(?P<id>[\d]+)', array(
    array(
        'methods' => WP_REST_Server::READABLE,
        'callback' => array($this, 'callback'),
        'permission_callback' => '__return_true',
    ),
));

/* ... */

function callback($request) {
    $id = $request['id'];
}

Какие значения ID могут быть переданы в обработчик? Правильный ответ: все - просто используйте /?rest_route=/(...)/1&id=hehehe.

get_users()

Некоторые плагины позволяют искать пользователей по части адреса электронной почты. Это позволяет слить e-mail любого пользователя, используя следующие шаги:

  • Перебор первой буквы доменного имени (поиск по @a, @b и т.д. и проверка, когда имя пользователя появляется в результатах поиска).
  • Запоминание первой буквы и использование ее для угадывания второй буквы. Допустим, доменное имя электронной почты пользователя начинается с g. Тогда можно перебором найти вторую букву (@ga, @gb, ...).
  • Повторяем описанные выше действия для остальной части адреса электронной почты.

В связи с этим я добавил проверку, которая предупреждает о вызове get_users(). К сожалению, помимо обнаружения уязвимостей данного типа, она также привела к многочисленным ложным срабатываниям.

Защита от XSS

Не делайте следующее:
Код:
if (/* обнаружен потенциальный XSS в $parameter */) die('Invalid parameter: ' . $parameter);

Несколько XSS-уязвимостей также были вызваны отладочными помощниками в виде:

Код:
echo "<!--";

var_dump($_POST);

echo "-->";

Проверка CAPTCHA

Не делайте этого:
Код:
if (isset($_POST['captcha'])) {
    /* проверяем капчу */
}

/* выполнить действие, которое должно быть защищено CAPTCHA */
Я наблюдал этот паттерн много раз, как для CAPTCHA, так и для несов.

Выводы

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

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

Эта техника может быть реализована и для других экосистем плагинов.

Многие из найденных мною уязвимостей легко предотвратить с помощью современных методов разработки программного обеспечения. Во многих плагинах WordPress HTML строится с помощью подверженной ошибкам кучи echo-заявлений, вместо языка шаблонов. Аналогично, конечные точки AJAX по умолчанию доступны для всех вошедших или не вошедших пользователей, вместо того чтобы требовать от разработчика фиксированного списка ролей или разрешений (так что им пришлось бы явно отмечать маршрут как доступный для всех вошедших пользователей). Внедрение методов, затрудняющих совершение ошибок, и поощрение их использования - это, к сожалению, то, что может сделать только команда WordPress, а не разработчики плагинов.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх