Introduction to XML-RPC. Programming competitions What is visible in the server logs


His post also shows how to do browser authentication, as below:
$request = xmlrpc_encode_request ("methodName" , array("methodParam" ));
$auth = base64_encode ($username . ":" . $password );
$header = (version_compare(phpversion(), "5.2.8"))
? array("Content-Type: text/xml" , "Authorization: Basic $auth " )
: "Content-Type: text/xml\r\nAuthorization: Basic$auth " ; //
$context = stream_context_create (array("http" => array(
"method" => "POST" ,
"header" => $header ,
"content" => $request
)));
$webservice = "http://www.example.com/rpc";
$file = file_get_contents($webservice, false, $context);
$response = xmlrpc_decode ($file);
if (xmlrpc_is_fault($response)) (
return "xmlrpc: $response [ faultString ] ($response [ faultCode ] )" ;
) else (
return $response ;
}
?>
1 - EDITOR NOTE: THIS IS A FIX FROM "SandersWang dt php at gmail dot com"

16 years ago

Binary strings (set with xmlrpc_set_type) go into a ...block like you"d expect. But after every 80th character, this function inserts the XML entity " ", which is a Unicode newline, as if to cause a line-wrap, which is admittedly silly.

Silly though it may be, it causes real problems for some XML-RPC servers, such as http://jakarta.apache.org/xmlrpc/ (nee Helma). Stripping out those entities with something like

$req = preg_replace("/ /", "", xmlrpc_encode_request("my.method", $args));

works around the problem.

11 years ago

It should be noted that encoding does not seem to encode anything, just specify what goes into the XML header.

We had problems with double-encoded UTF strings being saved to database when using this function, sending it of to a apache xml-rpc servlet and storing it in mysql database. It was solved by setting "escaping" to just "markup" and "encoding" to "UTF-8" (don't forget to set "utf-8" in xmlrpc_decode too).

It seems that UTF-8 encoded strings gets escaped with their bytes as entities instead of their characters as entites.

9 years ago

Ever tried transmitting an array like the following with xmlrpc?
$var1=array(7=>14,9=>18);

The output array looks quite different! It will look like that:
$var2=array(14,18);

The only solution i found is to prepend a space to the index:
$var3=array(" 7"=>14," 9"=>18);

Using that method you"ll get the right result. ($var1)

16 years ago

This function should be used by an XML-RPC client to create an XML payload for an XML-RPC request;

$params = "system.methodSignature" ;
$method = "system.methodHelp" ;
$request = xmlrpc_encode_request ($method, $params);
echo ($request);
?>

Produces;



system.methodHelp

system.methodSignature



The second argument recognizes the type of variable and generates the correct XML-RPC structure. See xmlrpc_encode() for more details.

12 years ago

Simple OO client with function Overload:

the php method test_helloworld is translated to xmlrpc method test.helloworld.

class RpcClient(

private $_methods;
private $_context;
private $_url;

Function __construct ($url, $user, $passwd) (
$auth = base64_encode(sprintf("%s:%s", $user,$passwd));
$this->_context = stream_context_create(array(
"http" => array(
"method" => "POST",
"header" => "Content-Type: text/xml\r\n".
"Authorization: Basic $auth" ,

)
));
$this->_url = $url;

$this->registerMethod("Test_HelloWorld");

Function __call($methodName, $params) (
if (array_key_exists($methodName,$this->_methods)) (
// on appelle la fonction RPC
$m = str_replace("_", ".", $methodName);
$r = xmlrpc_encode_request($m, $params,array("verbosity"=>"newlines_only"));
$c = $this->_context;
stream_context_set_option($c,"http","content",$r);
$f = file_get_contents($this->_url,false,$c);
$resp = xmlrpc_decode($f);
return $resp;
) else (
// on appelle la fonction de l"objet
call_user_method_array($methodName, $this,$params);
}
}

Private function registerMethod ($method) (
$this->_methods[$method] = true;
}

Introduction to XML-RPC

There are many different resources on the Internet that provide users with certain information. This does not mean ordinary static pages, but, for example, data retrieved from a database or archives. This could be an archive of financial data (exchange rates, securities quotes data), weather data, or more voluminous information - news, articles, messages from forums. Such information can be presented to the page visitor, for example, through a form, as a response to a request, or it can be generated dynamically each time. But the difficulty is that often such information is needed not so much by the end user - a person, but by other systems and programs that will use this data for their calculations or other needs.

Real example: a page of a banking website that displays currency quotes. If you access the page as a regular user, through a browser, you see all the page design, banners, menus and other information that “frames” the true purpose of the search - currency quotes. If you need to enter these quotes into your online store, then there is nothing else left to do but manually select the necessary data and transfer it to your website via the clipboard. And you will have to do this every day. Is there really no way out?

If you solve the problem head-on, then a solution immediately arises: a program (script on a website) that needs data receives a page from the server as a “regular user”, parses (parses) the resulting html code and extracts the necessary information from it. This can be done either with a regular regular expression, or using any html parser. The difficulty of the approach lies in its ineffectiveness. Firstly, to receive a small portion of data (data on currencies is literally a dozen or two characters), you need to receive the entire page, which is at least several tens of kilobytes. Secondly, with any change in the page code, for example, the design has changed or something else, our parsing algorithm will have to be redone. And this will take a fair amount of resources.

Therefore, the developers came to a decision - it is necessary to develop some kind of universal mechanism that would allow transparent (at the protocol and transmission medium level) and easy exchange of data between programs that can be located anywhere, be written in any language and run under any operating system. systems and on any hardware platform. Such a mechanism is now called the loud terms “Web services”, “SOAP”, “service-oriented architecture”. For data exchange, open and time-tested standards are used - the HTTP protocol is used to transmit messages (although other protocols can be used - SMTP, for example). The data itself (in our example, exchange rates) is transmitted packaged in a cross-platform format - in the form of XML documents. For this purpose, a special standard was invented - SOAP.

Yes, now web services, SOAP and XML are on everyone’s lips, they are beginning to be actively implemented, and large corporations like IBM and Microsoft are releasing new products designed to help the total implementation of web services.

But! For our example with exchange rates that must be transmitted from the bank’s website to the online store engine, such a solution will be very difficult. After all, the description of the SOAP standard alone takes up an obscene one and a half thousand pages, and that’s not all. For practical use, you will also have to learn how to work with third-party libraries and extensions (only starting from PHP 5.0 it includes a library for working with SOAP), and write hundreds and thousands of lines of your own code. And all this to get a few letters and numbers is obviously very cumbersome and irrational.

Therefore, there is another, one might say, alternative standard for information exchange - XML-RPC. It was developed with the participation of Microsoft by UserLand Software Inc and is designed for unified data transfer between applications over the Internet. It can replace SOAP when building simple services where all the “enterprise” capabilities of real web services are not needed.

What does the abbreviation XML-RPC mean? RPC stands for Remote Procedure Call. This means that an application (whether a script on the server or a regular application on the client computer) can transparently use a method that is physically implemented and executed on another computer. XML is used here to provide a universal format for describing the transmitted data. As a transport, the HTTP protocol is used to transmit messages, which allows you to seamlessly exchange data through any network devices - routers, firewalls, proxy servers.

And so, to use you need to have: an XML-RPC server that provides one or more methods, an XML-RPC client that can generate a correct request and process the server response, and also know the server parameters necessary for successful operation - address, method name and passed parameters.

All work with XML-RPC occurs in the “request-response” mode, this is one of the differences between the technology and the SOAP standard, where there are both the concepts of transactions and the ability to make delayed calls (when the server saves the request and responds to it at a certain time in future). These additional features are more useful for powerful corporate services; they significantly complicate the development and support of servers, and place additional requirements on developers of client solutions.

The procedure for working with XML-RPC begins with forming a request. A typical request looks like this:

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



TestMethod
Hello XML-RPC!


The first lines form the standard HTTP POST request header. Required parameters include host, data type (MIME type), which must be text/xml, and message length. The standard also specifies that the User-Agent field must be filled in, but can contain an arbitrary value.

Next comes the usual header of the XML document. The root element of the request is , there can be only one, and cannot contain such nodes as children. This means that one request can only call one method on the server.

Line TestMethod indicates that we are calling a method named TestMetod. If necessary, here you can specify the name of the program or module containing the method, as well as the path to it. The XML-RPC specification, although it imposes some restrictions on the set of characters that can be used to denote a method, how to interpret them is entirely dependent on the server implementation.

Next, the transmitted parameters are set. This section is used for this. Which can contain an arbitrary number of subelements Which contain the parameter described by the tag . We'll look at parameters and data types a little further. In our version, the method is passed one string parameter enclosed in the tag .

The description of all parameters is followed by closing tags. The request and response in XML-RPC are regular XML documents, so all tags must be closed. But there are no single tags in XML-RPC, although they are present in the XML standard.

Now let's look at the server's response. The HTTP response header is normal; if the request is successfully processed, the server returns an HTTP/1.1 200 OK response. Just as in the request, you must correctly specify the MIME type, message length and response generation date.

The response body itself is as follows:



true


Now instead of the root tag tag is indicated , which immediately contains the results of request processing. Unfortunately, the response does not pass the method name, so you should store it on the client side to avoid confusion if different methods are called at the same time.

If an error occurred while processing your request, instead of The response will contain the element , in which a structure describing the error will be nested. The error description contains a numeric error code and a text description.

Now let's take a brief look at data types in XML-RPC. There are 9 data types in total - seven simple types and 2 complex ones. Each type is described by its own tag or set of tags (for complex types).

Simple types:

Whole numbers- tag or ;

Boolean type- tag , can take both values ​​0/1 and true/false;

ASCII string- described by tag and can contain an arbitrary string of characters;

Floating point numbers- tag , may also contain a number sign, the fractional part is separated by a dot;

date and time- described by tag and must comply with the iso8601 format. For further processing in scripts, this format is a little inconvenient, so it is always converted when sending/receiving a request. This can be done by a special function within the library, or, if there is none, the developer must convert the date manually.

The last simple type is base64 encoded string, which is described by the tag . This type is universal; it can be used to transfer any data between the client and the server, although the volume of transferred data increases due to such encoding. But this is a consequence of the textual nature of the protocol and the XML format in particular.

Complex types are represented by structures and arrays. The structure is determined by the root element , which can contain an arbitrary number of elements , defining each member of the structure. A structure member is described by two tags: first, , describes the name of the member, second, , contains the value of the member (along with a tag describing the data type).

Arrays have no names and are described by the tag which contains one element , and one or more child elements , where specific data is specified. An array can contain any other types in any order, as well as other arrays, which allows you to describe multidimensional arrays. You can also describe an array of structures. But the fact that the array does not have a name complicates its use in some cases; to transfer complex data, they have to be repeatedly packed into other types (for example, to transfer several arrays, you can pack each array separately into a structure, and then create one array from these structures).

Of course, someone will say that such a list of data types is very poor and “does not allow you to expand.” Yes, if you need to transfer complex objects or large amounts of data, then it is better to use SOAP. And for small, undemanding applications, XML-RPC is quite suitable; moreover, very often even its capabilities turn out to be too many! Considering the ease of deployment, a very large number of libraries for almost any language and platform, and wide support in PHP, then XML-RPC often simply has no competitors. Although it cannot be immediately recommended as a universal solution - in each specific case it must be decided according to the circumstances.

XML-RPC technology is used in the WordPress system for various nice features such as pingbacks, trackbacks, remote site management without logging into the admin panel, etc. Unfortunately, attackers can use it to perform DDoS attacks on websites. That is, you create beautiful, interesting WP projects for yourself or to order, and at the same time, without suspecting anything, you can be part of a DDoS botnet. By connecting tens and hundreds of thousands of sites together, bad people create a powerful attack on their victim. Although at the same time your site also suffers, because... the load goes to the hosting where it is located.

Evidence of such bad activity can be in the server logs (access.log in nginx), containing the following lines:

103.238.80.27 - - "POST /wp-login.php HTTP/1.0" 200 5791 "-" "-"

But let's return to the XML-RPC vulnerability. Visually, it manifests itself in the slow opening of sites on your server or the inability to load them at all (502 Bad Gateway error). The technical support of my FASTVPS host confirmed my guesses and advised:

  1. Update WordPress to the latest version along with plugins. In general, if you follow, you might have read about the need to install the latest 4.2.3. due to security criticisms (just like previous versions). In short, it's good to update.
  1. Install the Disable XML-RPC Pingback plugin.

Disabling XML-RPC in WordPress

Previously, it seems to me that the option to enable/disable XML-RPC was somewhere in the system settings, but now I can’t find it there. Therefore, the easiest way to get rid of it is to use the appropriate plugin.

Find and download Disable XML-RPC Pingback or install it directly from the system admin panel. You do not need to configure anything additional, the module starts working immediately. It removes the pingback.ping and pingback.extensions.getPingbacks methods from the XML-RPC interface. Additionally, it removes X-Pingback from HTTP headers.

In one of the blogs I found a couple more options for removing the XML-RPC disabling.

1. Disable XML-RPC in the template.

To do this, add the following line to the theme's functions.php file:

Order Deny,Allow Deny from all

I personally did not use the last two methods, because... I connected the Disable XML-RPC Pingback plugin - I think it will be enough. Just for those who don’t like unnecessary installations, I suggested alternative options.

Starting at noon on Saturday, my server, where about 25 Wordpress sites are hosted, started experiencing severe slowdowns. Since I managed to survive the previous attacks ( , ) without being noticed, I did not immediately understand what was happening.

When I figured it out, it turned out that passwords were being brute-forced + many requests to XMLRPC.

As a result, we managed to cut it all off, although not immediately. Here are three simple tricks on how to avoid this.

These techniques are most likely known to everyone, but I stepped on a couple of mistakes that I didn’t find in the descriptions - maybe this will save someone time.

1. Stop the search, install the Limit Login Attempts plugin - install it, since other protections greatly slow down the server, for example, when using the Login Security Solution plugin, the server died after half an hour, the plugin heavily loads the database.

In the settings, be sure to turn on the “For proxy” checkbox - otherwise it will determine the IP of your server for everyone and automatically block everyone.
UPDATE, thank you, details are below in the comments - enable the “For proxy” checkbox only if the definition does not work when “Direct connection” is enabled

2. Disable XML-RPC - the Disable XML-RPC plugin (it’s easy to activate and that’s it).

3. Close wp-login.php - if you access the site via IP, the plugin does not work and the pickers continue to crash the site. To avoid this, add to .htaccess:

Order Deny,Allow Deny from all

We copy the wp-login file, rename it to any strange name, for example poletnormalny.php, and inside the file, use autocorrect to change all the wp-login.php inscriptions to poletnormalny.php.
That's it, now you can access the admin panel only using your file.

After these 3 simple steps, the sites began to fly again and peace came.

Well, suddenly it’s interesting

One of the options is to see if you are being attacked. This can be seen in the nginx logs (for example, here is the path for Debian /var/log/nginx access.log file).

WordPress has always had a built-in tool for remotely accessing your site. Indeed, sometimes you need to get to your site, but your computer is far from you. For a long time, the solution was a file called xmlrpc.php. However, in recent years this file has become more of a problem than a solution.

Below we will take a closer look at xmlrpc.php and why it was created. We'll also look at the common security issues it can cause and how to fix them for your WordPress site.

XML-RPC is a WordPress feature that allows data transfer, with HTTP serving as transport and XML for encoding. Since WordPress is not a closed system and often communicates with other systems, solutions have been found for this problem.

For example, let's say you want to post to your website from your mobile phone. You need to use the remote access provided by xmlrpc.php.

The main functionality of xmlrpc.php is the ability to connect to the site from a smartphone, the implementation of trackbacks and linkbacks from other sites, and some functions related to the Jetpack plugin.

Why was Xmlrpc.php created and how was it used?

The implementation of XML-RPC goes way back to the early days of WordPress and even before WordPress became WordPress.

Back in the early days of the internet, connections were very slow and the process of recording and publishing on the web was much more difficult and time consuming. Instead of making changes directly through the browser, most made them offline and then copied and pasted their content online. And this process was far from ideal.

The solution (at the time) was to create an offline blogging client where you could compose your content, then connect to your blog and publish it. This connection was made via XML-RPC. With core XML-RPC functionality, early applications using these connections gave people the ability to access their WordPress sites from other devices.

XML-RPC today

In 2008, with version 2.6 of WordPress, an option was introduced to enable or disable XML-RPC. However, with the release of the WordPress iPhone app, XML-RPC support was enabled by default and there was no option to disable it. It remains so today.

Of course, the functionality provided by this file has decreased significantly over time, and the file size has decreased from 83kb to 3kb, it no longer plays such a role as before.

XML-RPC Properties

With the new WordPress Application Programming Interface (API), we can expect XML-RPC to be disabled completely. Today this new API is still in testing and can only be enabled via a special plugin.

Although you can expect the API to be included directly into WordPress core in the future, eliminating the need for xmlrpc.php entirely.

The new API is not perfect, but it provides good, reliable security, unlike xmlrpc.php.

Why disable Xmlrpc.php

The biggest issue with XML-RPC is security. The problem is not directly related to XML-RPC, but it can be used to enable an attack on your site.

Of course, you can protect yourself with a very strong password and WordPress security plugins. But the best protection mode is to simply turn it off.

There are two main weaknesses of XML-RPC that have been exploited in the past.

The first one uses brute force attacks to gain access to your site. The attacker will try to gain access to your site using xmlrpc.php by trying different combinations of usernames and passwords. They can effectively use one command to test hundreds of different passwords. This allows them to bypass security tools that would normally detect and block brute force attacks.

The second is to take the site offline through a DDoS attack. Hackers will use the reverse notification in WordPress to send it to thousands of sites at the same time. This xmlrpc.php functionality gives hackers an almost infinite number of IP addresses to propagate a DDoS attack.

To check if XML-RPC is working on your site, you can run it using a tool called XML-RPC Validator. Run your site with the tool and if you get an error, it means you don't have XML-RPC support.

If you receive a success message, you can stop xmlrpc.php using one of the two approaches below.

Method 1: Disable Xmlrpc.php using a plugin

Disabling XML-RPC on your WordPress site is incredibly easy.

Go to section Plugins › Add new in your WordPress admin console. Find a plugin Disable XML-RPC and install it, it looks like the picture below:

Activate the plugin and you're done. This plugin will automatically insert the necessary code to disable XML-RPC.

However, remember that installed plugins may use parts of XML-RPC, and then disabling it may cause a conflict between the plugins or their individual parts and take them out of working mode.

If you only want to disable individual XML-RPC elements but allow other plugins and features to work, then look to plugins like these:

  • Stop XML-RPC Attack. This plugin will stop all XML-RPC attacks, but it will allow plugins like Jetpack and other automated tools and plugins to continue running by giving them access to xmlrpc.php files.
  • Control XML-RPC Publishing. This allows you to maintain control and publish remotely.

Method 2: Disable Xmlrpc.php manually

If you don't want to use a plugin and prefer to do it manually, follow this approach. It will stop all incoming xmlrpc.php requests before it is passed to WordPress.

Open the .htaccess file. You may have to enable 'show hidden files' in your file manager or FTP client to find this file.

Paste this code into the file .htaccess:

# Block WordPress xmlrpc.php requests order deny,allow deny from all allow from 123.123.123.123

Final Thoughts

Overall, XML-RPC was a solid solution to some of the problems that came with remote publishing on your WordPress site. However, at the same time, some security holes appeared that turned out to be quite dangerous for some WordPress site owners.

To keep your site secure, it is recommended to disable xmlrpc.php completely unless you need some of the features required by remote publishing and the Jetpack plugin. You can then use workaround plugins that allow you to use these features while patching the security holes.

Over time, we can expect XML-RPC functionality to become integrated into a new WordPress API that will support remote access without sacrificing security.

Have you blocked access to XML-RPC via a plugin or manually? Or were there any security issues because it was previously active? Share your experience in the comments below.