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

From: Date: Fri, 20 Feb 2015 14:37:24 +0000
Subject: Req #69090 [NEW]: add prefix/xor to cache keys/check permissions or separate caches
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-190844@lists.php.net to get a copy of this message
From:             simon at ikanobori dot jp
Operating system: linux/debian
PHP version:      5.5.22
Package:          opcache
Bug Type:         Feature/Change Request
Bug description:add prefix/xor to cache keys/check permissions or separate caches

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 bug report at https://bugs.php.net/bug.php?id=69090&edit=1
-- 
Try a snapshot (PHP 5.4):   https://bugs.php.net/fix.php?id=69090&r=trysnapshot54
Try a snapshot (PHP 5.5):   https://bugs.php.net/fix.php?id=69090&r=trysnapshot55
Try a snapshot (trunk):     https://bugs.php.net/fix.php?id=69090&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=69090&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=69090&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=69090&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=69090&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=69090&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=69090&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=69090&r=notwrong
Not enough info:            https://bugs.php.net/fix.php?id=69090&r=notenoughinfo
Submitted twice:            https://bugs.php.net/fix.php?id=69090&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=69090&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=69090&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=69090&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=69090&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=69090&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=69090&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=69090&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=69090&r=mysqlcfg



Thread (38 messages)

« previous php.bugs (#190844) next »