FIX can bypass the CSRF protection with url with domain inside

This commit is contained in:
Laurent Destailleur 2018-04-06 17:58:30 +02:00
parent 7877854693
commit 2d1183cbb7
2 changed files with 18 additions and 7 deletions

View File

@ -151,13 +151,23 @@ if (empty($dolibarr_strict_mode)) $dolibarr_strict_mode=0; // For debug in php s
// Note about $_SERVER[HTTP_HOST/SERVER_NAME]: http://shiflett.org/blog/2006/mar/server-name-versus-http-host
if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck))
{
if (! empty($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'GET' && ! empty($_SERVER['HTTP_HOST'])
&& (empty($_SERVER['HTTP_REFERER']) || ! preg_match('/'.preg_quote($_SERVER['HTTP_HOST'],'/').'/i', $_SERVER['HTTP_REFERER'])))
if (! empty($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'GET' && ! empty($_SERVER['HTTP_HOST']))
{
//print 'NOCSRFCHECK='.defined('NOCSRFCHECK').' REQUEST_METHOD='.$_SERVER['REQUEST_METHOD'].' HTTP_POST='.$_SERVER['HTTP_HOST'].' HTTP_REFERER='.$_SERVER['HTTP_REFERER'];
print "Access refused by CSRF protection in main.inc.php. Referer of form is outside server that serve the POST.\n";
print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file).\n";
die;
$csrfattack=false;
if (empty($_SERVER['HTTP_REFERER'])) $csrfattack=true; // An evil browser was used
else
{
$tmpa=parse_url($_SERVER['HTTP_HOST']);
$tmpb=parse_url($_SERVER['HTTP_REFERER']);
if ($tmpa['host'] != $tmpb['host']) $csrfattack=true;
}
if ($csrfattack)
{
//print 'NOCSRFCHECK='.defined('NOCSRFCHECK').' REQUEST_METHOD='.$_SERVER['REQUEST_METHOD'].' HTTP_POST='.$_SERVER['HTTP_HOST'].' HTTP_REFERER='.$_SERVER['HTTP_REFERER'];
print "Access refused by CSRF protection in main.inc.php. Referer of form is outside server that serve the POST.\n";
print "If you access your server behind a proxy using url rewriting, you might check that all HTTP header is propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file).\n";
die;
}
}
// Another test is done later on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on.
}

View File

@ -332,7 +332,8 @@ if (! defined('NOTOKENRENEWAL'))
$token = dol_hash(uniqid(mt_rand(),TRUE)); // Generates a hash of a random number
$_SESSION['newtoken'] = $token;
}
if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && ! empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)) // Check validity of token, only if option enabled (this option breaks some features sometimes)
if ((! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && ! empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN))
|| defined('CSRFCHECK_WITH_TOKEN')) // Check validity of token, only if option MAIN_SECURITY_CSRF_WITH_TOKEN enabled or if constant CSRFCHECK_WITH_TOKEN is set
{
if ($_SERVER['REQUEST_METHOD'] == 'POST' && ! GETPOST('token','alpha')) // Note, offender can still send request by GET
{