I want to use phpass-0.3 in Codeigniter, but I get the following error due to open_basedir
:
A PHP Error was encountered
Severity: Warning
Message: is_readable() [function.is-readable]: open_basedir restriction in effect. File(/dev/urandom) is not within the allowed path(s): (/home/phginep:/usr/lib/php:/usr/local/lib/php:/tmp)
Filename: phpass-0.3/PasswordHash.php
Line Number: 51
Following code:
function get_random_bytes($count)
{
$output = '';
if (is_readable('/dev/urandom') && //Line Number: 51
($fh = @fopen('/dev/urandom', 'rb'))) {
$output = fread($fh, $count);
fclose($fh);
}
if (strlen($output) < $count) {
$output = '';
for ($i = 0; $i < $count; $i += 16) {
$this->random_state =
md5(microtime() . $this->random_state);
$output .=
pack('H*', md5($this->random_state));
}
$output = substr($output, 0, $count);
}
return $output;
}
Is there anything I can do to get around this?
You have some options here:
1 - Download a dump from a true RNG (this one offers dumps from one based on radioactive decay) and use that, just be sure that you don't keep reading the same nn bytes. Kind of clunky, but an option.
2 - Have PHP execute something that reads from /dev/urandom
on its behalf (UGLY)
3 - Fall back on mt_rand()
(Also ugly, but I've seen this done):
for ($i = 0; $i < $count / 8; $i++) {
$output .= dechex(mt_rand(0, 0x7fffffff));
}
All options are clunky and ugly, unfortunately. The best thing to do would be sure that you don't have to deal with open_basedir
. Still, this particular annoyance could be worked around.
Finally - not likely to fly with your host, but perhaps worth a try:
You can ask your host to provide urandom
in your home directory so you can read it. Tell them you need to access urandom to generate random numbers so you can provide better security for your users, then ask them to run:
mknod urandom c 1 9
In your home directory. I just tried it on my own server, it works (but root needs to do it for you). There is no practical reason to keep you from using the system's pseudo random number generator, which you could do otherwise with anything other than PHP. This is actually the easiest way for them to let you have access to urandom
because it requires no exceptions in the PHP or vhost configuration for you.
Disallowing access to /dev/random
is a reasonable thing to do, since /dev/random
must be replenished by available (new) system entropy and might cause important things to block on read if exhausted which could happen often on low traffic servers. However, /dev/urandom
is guaranteed to never block since it just reuses the internal entropy pool once exhausted, which is why it's a lesser quality source.
Note
I'm not saying the idea of open_basedir
is a bad one, but it breaks good code too. A classic chroot
is much better, but harder, which is why you run into open_basedir
much more than you do a real chroot. At the minimum, any program should be able to access the null
, zero
and urandom
devices on a server.