Req #69090 [Com]: add prefix/xor to cache keys/check permissions or separate caches

From: Date: Thu, 27 Oct 2016 05:39:46 +0000
Subject: Req #69090 [Com]: add prefix/xor to cache keys/check permissions or separate caches
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-205036@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=69090&edit=1

 ID:                 69090
 Comment by:         kmark937 at gmail dot com
 Reported by:        simon at ikanobori dot jp
 Summary:            add prefix/xor to cache keys/check permissions or
                     separate caches
 Status:             Analyzed
 Type:               Feature/Change Request
 Package:            opcache
 Operating System:   linux/debian
 PHP Version:        5.6.5
 Block user comment: N
 Private report:     N

 New Comment:

I'm concerned about this issue since it has the potential to be a security deal-breaker for
Zend OPcache when used on (as an example) a shared-hosting platform.

With that said I'm unable to replicate this using michal_micko's instructions for mod_php
and open_basedir configurations.

I used the same exact two VirtualHosts, directory tree, and file contents. I restarted apache,
accessed http://app2 first and then http://app1
but both displayed their proper "bad" and "good" texts respectively.

Ubuntu 14.04.5 LTS (as opposed to Debian 8.1)
Apache 2.4.7 (Ubuntu) (as opposed to 2.4.10, default config plus VirtualHosts)
PHP 5.6.27-1+deb.sury.org~trusty+1 (as opposed to 5.6.14-0+deb8u1, default config)

Possibly relevant:
opcache.enable = On
opcache.optimization_level = 0x7FFFBFFF
opcache.revalidate_path = Off
opcache.use_cwd = On
opcache.validate_timestamps = On

One potentially major difference between my config and michal_micko's is that I do not have any
XCache modules or Xdebug loaded. I would think, with except perhaps the PHP version, that is the
only major configuration difference between my set up and michal_micko's.

For me it looks safe to use PHP 5.6 OPcache + mod_php + open_basedir. When I dump the output of
opcache_get_status() I see only full paths for both the "full_path" value and the array
keys. I believe this is the use_cwd option doing its job. The only additional "securing"
that I see is setting restrict_api to something out of reach or adding opcache_* functions to
disable_functions.

I'd greatly appreciate it if anyone is able to correct or confirm what I've found.


Previous Comments:
------------------------------------------------------------------------
[2016-06-03 12:59:08] rgpublic at gmx dot net

This is probably related:

https://bugs.php.net/bug.php?id=67481

I also find it stunning that - at the very least - PHP doesn't warn about this or even better
refuse to start in this configuration. This is a serious security issue and all too easy to
overlook. Took me a while to figure out whats actually happening. This can lead to very mysterious
errors. Fragments or error messages of other unrelated sites on the same server suddenly showing up
and so on. 

Can anybody confirm that "opcache.optimization_level=0" is really a solid workaround that
can be used in production? There should be no information leak whatsoever. No files. No data. No
code. No nothing. That's why we have a chrooted environment in the first place. But obviously
I'd rather have an optimzation level 0 than no opcache at all.

------------------------------------------------------------------------
[2016-03-29 09:51:39] admin at 3dr dot org

Is this still beeing considered as a bug or should we just give up on chroot+opcache?

------------------------------------------------------------------------
[2015-11-04 09:14:05] michal_micko at centrum dot cz

important note to the previous example:
---------------------------------------
PHP is running as Apache module

------------------------------------------------------------------------
[2015-11-03 22:42:07] michal_micko at centrum dot cz

I replicate this problem with two VirtualHosts (using open_basedir).

OS: Debian 8.1
php -v
PHP 5.6.14-0+deb8u1 (cli) (built: Oct  4 2015 16:13:10) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with XCache v3.2.0, Copyright (c) 2005-2014, by mOo
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
    with XCache Optimizer v3.2.0, Copyright (c) 2005-2014, by mOo
    with XCache Cacher v3.2.0, Copyright (c) 2005-2014, by mOo
    with XCache Coverager v3.2.0, Copyright (c) 2005-2014, by mOo

Apache: 2.4.10

VirtualHosts:
-------------
cat 050-opcache-fail.conf 
<VirtualHost *:80>
    ServerName app1
    DocumentRoot /var/www/app1/web
    php_admin_value open_basedir /var/www/app1
    <Directory /var/www/app1/web>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        #Order allow,deny
        #Allow from All
        Require all granted
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName app2
    DocumentRoot /var/www/app2/web
    php_admin_value open_basedir /var/www/app2
    <Directory /var/www/app2/web>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        #Order allow,deny
        #Allow from All
        Require all granted
    </Directory>
</VirtualHost>

Example - PHP apps - typical using with composer (dummy):
---------------------------------------------------------
apps directory structures: /var/www/

app1
  vendor
    third
      party
        lib.php
    autoload.php
  web
    index.php

app2
  vendor
    third
      party
        lib.php
    autoload.php
  web
    index.php


web/index.php (same app1 and app2):
-----------------------------------
<?php
require_once __DIR__ . '/../vendor/autoload.php';

echo (new third\party\lib())->getName();
?>


vendor/autoload.php (same app1 and app2):
-----------------------------------------
<?php
require_once __DIR__ . '/third/party/lib.php';
?>


vendor/third/party/lib.php (app1):
----------------------------------
<?php
namespace third\party;

class lib
{
    public function getName()
    {
        return 'good library';
    }
}
?>


vendor/third/party/lib.php (app2):
----------------------------------
<?php
namespace third\party;

class lib
{
    public function getName()
    {
        return 'bad hacked library';
    }
}
?>


Security issue:
---------------
It would be a problem in webhostings. After web server restart just run bad app2 as first.



Workaround:
-----------
opcache.optimization_level=0

------------------------------------------------------------------------
[2015-09-24 18:32:19] toni at lygon dot net

I can replicate this with php5-fpm 5.5.9+dfsg-1ubuntu4.11.

I baffled how a huge security / usability problem like this can exist, yet nobody gives a poop about
it.
We've got a server with multiple sites chrooted using the same directory structure inside the
chrooted /.
Obviously this causes fatal problems as there are conflicts, like index.php in those hosts causing
it to randomly load from any of those.

Because of this, opcache can not be used as we can't change the directory structure.

Someone, please investigate this!

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=69090


--
Edit this bug report at https://bugs.php.net/bug.php?id=69090&edit=1


Thread (38 messages)

« previous php.bugs (#205036) next »