Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mcrypt library not being used while installed #111

Closed
ApplicationBuilders opened this issue Jul 15, 2016 · 8 comments
Closed

mcrypt library not being used while installed #111

ApplicationBuilders opened this issue Jul 15, 2016 · 8 comments

Comments

@ApplicationBuilders
Copy link

ApplicationBuilders commented Jul 15, 2016

On a VPS (CentOS 6.7, PHP 5.6.23, managed with Plesk and Parallels Virtuozzo) of a customer of ours we installed symfony for a project.
The random_compat library was one of the dependencies.
For some reason /dev/urandom was (and still isn't) one of the directories outputed by ini_get('open_basedir')

So the check for /dev/urandom fails as we can't access it from php.
Mcrypt library however is installed so it tries to test for this.
The following if statement fails however because the test for /dev/urandom has failed

if (
        !function_exists('random_bytes')
        &&
        PHP_VERSION_ID >= 50307
        &&
        extension_loaded('mcrypt')
        &&
        (DIRECTORY_SEPARATOR !== '/' || $RandomCompatUrandom)
) 

$RandomCompatUrandom is at first defined by the check for /dev/urandom by DIRECTORY_SEPARATOR === '/', however it is later in that if statement redefined to check if we have /dev/urandom in accesable directories

$RandomCompatUrandom = (array() !== array_intersect(
    array('/dev', '/dev/', '/dev/urandom'),
    $RandomCompat_open_basedir
));

Because we can't use /dev/urandom, we therefore also can't access mcrypt anymore, which seems to be a flaw in the processing logic.

A proper fix i leave to you, as ours disregards windows possibility and is therefor for our system only.

@paragonie-scott
Copy link
Member

Because we can't use /dev/urandom, we therefore also can't access mcrypt anymore, which seems to be a flaw in the processing logic.

There's a reason for that: mcrypt_create_iv() fails if open_basedir prevents /dev/urandom from being read.

@chill1Penguin
Copy link

There's a reason for that: mcrypt_create_iv() fails if open_basedir prevents /dev/urandom from being read.

I do not find this true with my web host (PHP 5.6.23 on Linux). mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM) succeeds despite the fact that '/dev', '/dev/', or '/dev/urandom' is NOT included in open_basedir.

@paragonie-scott
Copy link
Member

Is open_basedir disabled?

@chill1Penguin
Copy link

No, it is set to /home/[username]:/usr/lib/php:/usr/local/lib/php:/tmp.

@BreyndotEchse
Copy link

I can confirm this issue. is_readable('/dev/urandom') throws an error stating open_basedir restriction in effect. But yet mcrypt_create_iv(32, MCRYPT_DEV_URANDOM) returns the expected output:

DIRECTORY_SEPARATOR === '/': 1
ini_get('open_basedir'): /var/www/vhosts/projects.devb/:/tmp/:/var/www/httpdocs/lib/
DIRECTORY_SEPARATOR === '/': 0
>>>> Error: is_readable(): open_basedir restriction in effect. File(/dev/urandom) is not within the allowed path(s): (/var/www/vhosts/projects.devb/:/tmp/:/var/www/httpdocs/lib/)
is_readable('/dev/urandom'): 0
PHP_VERSION_ID >= 50307 && extension_loaded('mcrypt'): 1
current(unpack('H*', mcrypt_create_iv(32, MCRYPT_DEV_URANDOM))): 47192b3e468c2a27a5f25ad9dcaf51dbb453813dcc82c4657e45a941281ac3f3

Output generated by this script:

<?php
set_error_handler(function($errno, $errstr, $errfile = null, $errline = null, array $errcontext = []) {
    printf(">>>> Error: %s%s", $errstr, PHP_EOL);
});

printf("DIRECTORY_SEPARATOR === '/': %b%s", DIRECTORY_SEPARATOR === '/', PHP_EOL);
printf("ini_get('open_basedir'): %s%s", ini_get('open_basedir'), PHP_EOL);

$RandomCompat_basedir = ini_get('open_basedir');
if (!empty($RandomCompat_basedir)) {
    $RandomCompat_open_basedir = explode(
        PATH_SEPARATOR,
        strtolower($RandomCompat_basedir)
    );
    printf("DIRECTORY_SEPARATOR === '/': %b%s", array() !== array_intersect(
        array('/dev', '/dev/', '/dev/urandom'),
        $RandomCompat_open_basedir
    ), PHP_EOL);
}

printf("is_readable('/dev/urandom'): %b%s", is_readable('/dev/urandom'), PHP_EOL);
printf("PHP_VERSION_ID >= 50307 && extension_loaded('mcrypt'): %b%s", PHP_VERSION_ID >= 50307 && extension_loaded('mcrypt'), PHP_EOL);
printf("current(unpack('H*', mcrypt_create_iv(32, MCRYPT_DEV_URANDOM))): %s%s", current(unpack('H*', mcrypt_create_iv(32, MCRYPT_DEV_URANDOM))), PHP_EOL);

@paragonie-scott
Copy link
Member

OK, one of two things happened and I'm not sure which:

  1. I'm totally wrong and believe something that isn't true about how PHP behaved in an older version.
  2. There was an edge case before where the problem we're working around was totally relevant.

@paragonie-scott
Copy link
Member

I'm going to do a patch release today, and then if this turns out to be an error on my part, I'll fix my mistake and do another patch release with an appropriate fix.

@paragonie-scott
Copy link
Member

I never got the patch release out, did I?

67f5061

Will release v2.0.4 right now (and if it causes problems for others, v2.0.5 with a revert ASAP).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants