Sunday, June 23, 2013

Zend opcode cacher in PHP 5.5: a security perspective

The new zend opcache extension built into the latest version of PHP is, as we've checked, a bit faster than the current best - XCache. There's, however, a security concern.

Both extensions make it possible to clear the whole cache programatically (from within a script). In Zend it's the opcache_reset() function and in XCache it's xcache_clear_cache(XC_TYPE_PHP).

If you run shared hosting, you allow your users to execute arbitrary code in your PHP interpreter. This, naturally, includes the two functions mentioned above. If you rely on the opcode cache to provide desired level of service for your customers, you don't want them to clear everybody's caches. If a malicious or badly written script clears your cache, say, every minute - there is no benefit from caching. The whole idea is that you cache the most used files once, and use the cached version from RAM. What this means for a shared host is increased CPU and possibly disk IO usage. In some cases, this can turn into a Denial of Service (DoS) attack.

So let's take this simple script and see what Zend Opcache will do when you execute it:

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

opcache_reset();

echo 'OK';

Well, Zend happily cleared the cache. Now let's see what XCache does:

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

xcache_clear_cache(XC_TYPE_PHP);

echo 'OK';

The XCache developer envisioned this problem. Certain functions, which affect other users' experience, trigger a login page. The username and password is set by an administrator system-wide in php.ini and is not viewable by regular users.

Conclusion

If you run a shared host and want to speed it up using opcode caching, you should use XCache rather than the new Zend Opcache. Zend is only better by 10%, it's not a number worth risking a DoS attack. On the other hand, if you and only you control the code that's run on your servers, this security issue won't affect you.

Possible fix

You could (and should) use the disable_functions directive in php.ini

(Need help installing XCache or securing Zend?)

No comments:

Post a Comment