Req #69090 [Com]: add prefix/xor to cache keys/check permissions or separate caches
| From: | thesparkdevelopment at gmail dot com | Date: | Sun, 14 Jun 2015 09:04:03 +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-193455@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: thesparkdevelopment 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:
4 month for critical fix... it's bad...
Previous Comments:
------------------------------------------------------------------------
[2015-02-22 01:21:14] rasmus@php.net
Yes, it was one of the features we lost by dropping APC. It has been on our radar for a while to
fix, but nobody has gotten to writing the code yet.
------------------------------------------------------------------------
[2015-02-21 11:15:14] simon at ikanobori dot jp
I've written a more extensive post with more examples here: https://ikanobori.jp/php55-opcache-shared-hosting.html
Inodes seem to be a good idea, I think APC does it that way?
------------------------------------------------------------------------
[2015-02-21 02:00:40] rasmus@php.net
I think the easiest would be to simply add an option to use a file's device+inode in addition
to, or instead of, the full path. We have discussed this a few times, but nobody has gotten around
to an implementation yet.
------------------------------------------------------------------------
[2015-02-20 14:38:50] simon at ikanobori dot jp
Correct PHP version.
------------------------------------------------------------------------
[2015-02-20 14:37:23] simon at ikanobori dot jp
Description:
------------
PHP's opcache seems to create keys for files it caches based on their filepath (including the
cwd when the option opcache.use_cwd is set).
When turning on opcache in commonly used hosting environments where users are chrooted it is very
easy to get key collissions as the full path of a file in a chroot can commonly be /wp-config.php.
The file that was accessed on this path first will be stored by opcache and be used by any
interpreters executing the same file later on.
Even without a chroot it is often easy to predict where files of another user on the same server
will be located and they can still be included circumventing any file permissions set on these files
even if PHP executes as the correct user (made even more trivial to figure out interesting files if
access to the opcache_get_status() function is not restricted by the host).
Example is in the "test script" below which shortly shows my relevant config lines.
It'd be neat if opcache could implement a runtime config variable to give to an interpreter
with a value that mashes up the key by prefixing or xor'ing it without the possibility of being
overwritten from within the script.
Alternatively it might be possible to use different parts of shm based on a configuration option so
the cache is per-user.
Test script:
---------------
# Permissions on both directories and files are set to rwx for user only
root@debian:/home# ls -l .
total 12
drwx------ 2 one one 4096 Feb 20 12:45 one
drwx------ 2 two two 4096 Feb 20 12:45 two
root@debian:/home# ls -l one/
total 4
-rw------- 1 one one 25 Feb 20 12:42 one.php
root@debian:/home# ls -l two/
total 4
-rw------- 1 two two 46 Feb 20 12:44 two.php
# one.php just sets a single variable
root@debian:/home# cat one/one.php
<?php
$one = "one";
?>
# This file tries to include the non-existent "/one.php" in its chroot
root@debian:/home# cat two/two.php
<?php
include "/one.php";
print $one;
?>
# FPM processes are configured to run as the user
root@debian:/home# grep -r "user =" /etc/php5/fpm/pool.d/
/etc/php5/fpm/pool.d/1.conf:user = one
/etc/php5/fpm/pool.d/2.conf:user = two
# FPM processes also run chrooted into the homedirs
root@debian:/home# grep -r "chroot " /etc/php5/fpm/pool.d/
/etc/php5/fpm/pool.d/1.conf:chroot = /home/one
/etc/php5/fpm/pool.d/2.conf:chroot = /home/two
# Request one.php on pool one
root@debian:/home# curl http://1.localhost/one.php
# Request two.php on pool two
root@debian:/home# curl http://2.localhost/two.php
one
# That's the content of /one.php which is owned by user one, in its own chroot
# being served by user two from a different chroot while user two doesnt even
# have read permissions on the file.
Expected result:
----------------
Users can only access their own files (when configured correctly).
Actual result:
--------------
Users can access other users' files when previously accessed by opcache cross chroots and
ignoring filesystem permissions.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=69090&edit=1