Критическая уязвимость WordPress и Drupal

Активист

Активист
Команда форума
Недавно вышла инфа:

...
Уязвимость позволяет вызвать полный отказ в работе сайта небольшим XML-документом размером в несколько сотен килобайт. Для этого в документе нужно определить несколько сущностей большой длины (в несколько десятков тысяч символов) и вызвать их несколько десятков тысяч раз. При обработке 200-килобайтовый документ превратится в несколько десятков гигабайт и займёт всю доступную память сервера.
...
http://tjournal.ru/paper/wordpress-critical-bug

Сам баг фикс: https://github.com/WordPress/WordPress/commit/824ca5b0309eef4229f3b8640114d889fd4a9b87

Код:
{
// first remove the XML declaration
// merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
- $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr($this->message, 0, 100), 1);
- $this->message = substr_replace($this->message, $header, 0, 100);
- if (trim($this->message) == '') {
+ $header = preg_replace( '/<\?xml.*?\?'.'>/s', '', substr( $this->message, 0, 100 ), 1 );
+ $this->message = trim( substr_replace( $this->message, $header, 0, 100 ) );
+ if ( '' == $this->message ) {
return false;
}
+
+ // Then remove the DOCTYPE
+ $header = preg_replace( '/^<!DOCTYPE[^>]*+>/i', '', substr( $this->message, 0, 200 ), 1 );
+ $this->message = trim( substr_replace( $this->message, $header, 0, 200 ) );
+ if ( '' == $this->message ) {
+ return false;
+ }
+
+ // Check that the root tag is valid
+ $root_tag = substr( $this->message, 0, strcspn( substr( $this->message, 0, 20 ), "> \t\r\n" ) );
+ if ( '<!DOCTYPE' === strtoupper( $root_tag ) ) {
+ return false;
+ }
+ if ( ! in_array( $root_tag, array( '<methodCall', '<methodResponse', '<fault' ) ) ) {
+ return false;
+ }
+
+ // Bail if there are too many elements to parse
+ $element_limit = 30000;
+ if ( function_exists( 'apply_filters' ) ) {
+ $element_limit = apply_filters( 'xmlrpc_element_limit', $element_limit );
+ }
+ if ( $element_limit && 2 * $element_limit < substr_count( $this->message, '<' ) ) {
+ return false;
+ }
+
$this->_parser = xml_parser_create();
// Set XML parser to take the case of tags in to account
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
Вопрос к обладателям. Как там вообще эти XML могут быть залиты и как они кладут сервер? Где теоретический фейл?
 
Последнее редактирование:

Активист

Активист
Команда форума
Но не понятно... Видимо код там дальше уныл. У меня каталог из XML-ки русской (1С) с 80 тысячами товаров парсится с 20 мегабайтами памяти (пиковое использование). Как с 200 КБ XML можно положить сервер ... Причем хостеры рассылку сделали, даже те что на облаках, что мол нужно срочно обноситься. Заначит что-то конкретное положили. Вопрос, как в бущущем учесть их ошибки. Как из 200 КБ в десятки гигибайт разрастись.. Плюс MEM лимит все-таки, или там черел либу XML льется?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Написано же XMLRPC. Это такая шняга, позволяющая постить контент в бложек из десктопных клиентов.
 

Активист

Активист
Команда форума
Написано же XMLRPC. Это такая шняга, позволяющая постить контент в бложек из десктопных клиентов.
ну доступ к инструментам XMLRPC из вне как-то глупо, епт))) Обычно обмен XML связывают с доверенными источниками.
 

Активист

Активист
Команда форума
Ясно все с ними. И кусок их костыля кода тоже ясен - выпиливают из XML все DOCTYPE и ссылки, и проверяют количество тегов.
 

fixxxer

К.О.
Партнер клуба
Какие-то странные костыли. Обычный системный лимит памяти (не php-шный memory_limit, конечно, а на уровне ОС) прекрасно справится: ну упадет воркер и перезапустится, не вижу в этом проблемы.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я подобную ошибку нашел в yii почти сразу как взялся за него - там валидация email была по регекспу с выделением вида (.*) - элементарное переполнение стека на любой форме регистрации,
да и в симфони проблему такого плана можно поискать при желании
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
С регулярками основная проблема в том, что pcre - говно. Нормальной реализации регулярных выражений не нужен стек вообще (если не рассматривать perl extensions типа ?R, но (.*) уж точно к этому не имеет отношения).
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
это понятно, а с XML проблема в том, что парсер строит DOM-структуру, проблемы просто есть, они известны давно, но иногда их не учитывают
 

Активист

Активист
Команда форума
это понятно, а с XML проблема в том, что парсер строит DOM-структуру, проблемы просто есть, они известны давно, но иногда их не учитывают
Вот вот.. Вместо того, что бы внедрить ограничение в либе, и константу отменяющую это ограничение, нужно писать костыли. Так, например, мелкомягкие опубликовали эту возможность DDoS еще в ноября 2009.
 

hell0w0rd

Продвинутый новичок
Ой, да ладно, достаточно в симфони говнокода. Хотел nikic'овский механизм роутинга добавить - так там оказалась какая-то хренота, а не архитектура роутера, во все дыры пихнули свой expression-language, чтобы говнокодилось легче)
 

Вурдалак

Продвинутый новичок
Дайте мне в очередной раз постебаться над CMS, уйдите отсюда.

Нет, там бы написали XmlNodeLimitChecker, который бы implements XmlNodeVisitor, да еще бы в конфиг вынесли количество элементов для limit'а :D

Ой, да ладно, достаточно в симфони говнокода. Хотел nikic'овский механизм роутинга добавить - так там оказалась какая-то хренота, а не архитектура роутера, во все дыры пихнули свой expression-language, чтобы говнокодилось легче)
А при чем тут nikic и его роутер?
 
Сверху