Improve randomness of security tokens (#1490529)

pull/297/head
Aleksander Machniak 9 years ago
parent f75bc5c24b
commit 26086981a2

@ -32,7 +32,7 @@ RewriteRule ^favicon\.ico$ skins/larry/images/favicon.ico
# security rules:
# - deny access to files not containing a dot or starting with a dot
# in all locations except installer directory
RewriteRule ^(?!installer|[a-f0-9]{16})(\.?[^\.]+)$ - [F]
RewriteRule ^(?!installer|[a-zA-Z0-9]{16})(\.?[^\.]+)$ - [F]
# - deny access to some locations
RewriteRule ^/?(\.git|\.tx|SQL|bin|config|logs|temp|tests|program\/(include|lib|localization|steps)) - [F]
# - deny access to some documentation files

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Security: Improve randomness of security tokens (#1490529)
- Security: Use random security tokens instead of hashes based on encryption key (#1490404)
- Security: Improved encrypt/decrypt methods with option to choose the cipher_method (#1489719)
- Make optional adding of standard signature separator - sig_separator (#1487768)

@ -810,7 +810,7 @@ class rcmail extends rcube
// remove old token from the path
$base_path = rtrim($base_path, '/');
$base_path = preg_replace('/\/[a-f0-9]{' . strlen($token) . '}$/', '', $base_path);
$base_path = preg_replace('/\/[a-zA-Z0-9]{' . strlen($token) . '}$/', '', $base_path);
// this need to be full url to make redirects work
$absolute = true;

@ -1090,25 +1090,31 @@ class rcube_utils
}
/**
* Generate a ramdom string
* Generate a random string
*
* @param int $length String length
* @param bool $raw Return RAW data instead of hex
* @param bool $raw Return RAW data instead of ascii
*
* @return string The generated random string
*/
public static function random_bytes($length, $raw = false)
{
$rlen = $raw ? $length : ceil($length / 2);
$random = openssl_random_pseudo_bytes($rlen);
// Use PHP7 true random generator
if (function_exists('random_bytes')) {
$random = @random_bytes($length);
}
if (!$random) {
$random = openssl_random_pseudo_bytes($length);
}
if ($raw) {
return $random;
}
$random = bin2hex($random);
$random = self::bin2ascii($random);
// if the length wasn't even...
// truncate to the specified size...
if ($length < strlen($random)) {
$random = substr($random, 0, $length);
}
@ -1116,6 +1122,50 @@ class rcube_utils
return $random;
}
/**
* Convert binary data into readable form (containing a-zA-Z0-9 characters)
*
* @param string $input Binary input
*
* @return string Readable output
*/
public static function bin2ascii($input)
{
// Above method returns "hexits".
// Based on bin_to_readable() function in ext/session/session.c.
// Note: removed ",-" characters from hextab
$hextab = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$nbits = 6; // can be 4, 5 or 6
$length = strlen($input);
$result = '';
$char = 0;
$i = 0;
$have = 0;
$mask = (1 << $nbits) - 1;
while (true) {
if ($have < $nbits) {
if ($i < $length) {
$char |= ord($input[$i++]) << $have;
$have += 8;
}
else if (!$have) {
break;
}
else {
$have = $nbits;
}
}
// consume nbits
$result .= $hextab[$char & $mask];
$char >>= $nbits;
$have -= $nbits;
}
return $result;
}
/**
* Format current date according to specified format.
* This method supports microseconds (u).

@ -430,7 +430,7 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
*/
function test_random_bytes()
{
$this->assertSame(15, strlen(rcube_utils::random_bytes(15)));
$this->assertRegexp('/^[a-zA-Z0-9]{15}$/', rcube_utils::random_bytes(15));
$this->assertSame(15, strlen(rcube_utils::random_bytes(15, true)));
$this->assertSame(1, strlen(rcube_utils::random_bytes(1)));
$this->assertSame(0, strlen(rcube_utils::random_bytes(0)));

Loading…
Cancel
Save