mirror of
https://github.com/phpbb/phpbb.git
synced 2025-03-13 20:28:44 +01:00
Merge pull request #38 from phpbb/ticket/security/210
[ticket/security/210] Prevent using IP addresses or ports for remote avatar
This commit is contained in:
commit
0b405a2cdc
@ -85,8 +85,11 @@ class remote extends \phpbb\avatar\driver\driver
|
||||
}
|
||||
|
||||
// Check if this url looks alright
|
||||
// This isn't perfect, but it's what phpBB 3.0 did, and might as well make sure everything is compatible
|
||||
if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.('. implode('|', $this->allowed_extensions) . ')$#i', $url))
|
||||
// Do not allow specifying the port (see RFC 3986) or IP addresses
|
||||
if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.('. implode('|', $this->allowed_extensions) . ')$#i', $url) ||
|
||||
preg_match('@^(http|https|ftp)://[^/:?#]+:[0-9]+[/:?#]@i', $url) ||
|
||||
preg_match('#^(http|https|ftp)://(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])#i', $url) ||
|
||||
preg_match('#^(http|https|ftp)://(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){0,5}(?:[\dA-F]{1,4}(?::[\dA-F]{1,4})?|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:)|(?:::))#i', $url))
|
||||
{
|
||||
$error[] = 'AVATAR_URL_INVALID';
|
||||
return false;
|
||||
|
@ -134,6 +134,16 @@ class upload extends \phpbb\avatar\driver\driver
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do not allow specifying the port (see RFC 3986) or IP addresses
|
||||
// remote_upload() will do its own check for allowed filetypes
|
||||
if (preg_match('@^(http|https|ftp)://[^/:?#]+:[0-9]+[/:?#]@i', $url) ||
|
||||
preg_match('#^(http|https|ftp)://(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])#i', $url) ||
|
||||
preg_match('#^(http|https|ftp)://(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){0,5}(?:[\dA-F]{1,4}(?::[\dA-F]{1,4})?|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:)|(?:::))#i', $url))
|
||||
{
|
||||
$error[] = 'AVATAR_URL_INVALID';
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $upload->remote_upload($url, $this->mimetype_guesser);
|
||||
}
|
||||
else
|
||||
|
@ -372,4 +372,59 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case
|
||||
'avatar_height' => 0,
|
||||
), $row);
|
||||
}
|
||||
|
||||
public function data_remote_avatar_url()
|
||||
{
|
||||
return array(
|
||||
array('127.0.0.1:91?foo.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
array(gethostbyname('secure.gravatar.com') . '/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
array('secure.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80),
|
||||
array(gethostbyname('secure.gravatar.com') . ':120/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
array('secure.gravatar.com:80/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
array('secure.gravatar.com:80?55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
array('secure.gravatar.com?55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')), // should be a 404
|
||||
array('2001:db8:0:0:0:0:2:1/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
array('secure.gravatar.com/2001:db8:0:0:0:0:2:1/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
array('secure.gravatar.com/127.0.0.1:80/avatar/55502f40dc8b7c769880b10874abc9d0.jpg', 80, 80, array('AVATAR_URL_INVALID')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_remote_avatar_url
|
||||
*/
|
||||
public function test_remote_avatar_url($url, $width, $height, $expected_error = array())
|
||||
{
|
||||
global $phpbb_root_path, $phpEx;
|
||||
|
||||
if (!function_exists('get_preg_expression'))
|
||||
{
|
||||
require($phpbb_root_path . 'includes/functions.' . $phpEx);
|
||||
}
|
||||
|
||||
$this->config['server_name'] = 'foobar.com';
|
||||
|
||||
/** @var \phpbb\avatar\driver\remote $remote_avatar */
|
||||
$remote_avatar = $this->manager->get_driver('avatar.driver.remote', false);
|
||||
|
||||
$request = new phpbb_mock_request(array(), array(
|
||||
'avatar_remote_url' => $url,
|
||||
'avatar_remote_width' => $width,
|
||||
'avatar_remote_height' => $height,
|
||||
));
|
||||
|
||||
$user = new \phpbb\user('\phpbb\datetime');
|
||||
$row = array();
|
||||
$error = array();
|
||||
|
||||
$return = $remote_avatar->process_form($request, null, $user, $row, $error);
|
||||
if (count($expected_error) > 0)
|
||||
{
|
||||
$this->assertFalse($return);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->assertNotEquals(false, $return);
|
||||
}
|
||||
$this->assertSame($expected_error, $error);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user