mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-04-29 23:32:54 +09:00
Merge branch 'develop' into pr/csrf-token
This commit is contained in:
commit
a3ef122b57
68 changed files with 2115 additions and 1361 deletions
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* RX_VERSION is the version number of the Rhymix CMS.
|
||||
*/
|
||||
define('RX_VERSION', '1.8.33');
|
||||
define('RX_VERSION', '1.8.34');
|
||||
|
||||
/**
|
||||
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ return array(
|
|||
'auto_login' => true,
|
||||
'errorlogger' => true,
|
||||
'fix_mysql_utf8' => true,
|
||||
'homepage' => true,
|
||||
'member_communication' => true,
|
||||
'multidomain' => true,
|
||||
'seo' => true,
|
||||
'session_shield' => true,
|
||||
'smartphone' => true,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ return array(
|
|||
),
|
||||
'url' => array(
|
||||
'default' => null,
|
||||
'unregistered_domain_action' => 'redirect_301',
|
||||
'http_port' => null,
|
||||
'https_port' => null,
|
||||
'ssl' => 'none',
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ class DateTime
|
|||
{
|
||||
return $_SESSION['RHYMIX']['timezone'];
|
||||
}
|
||||
elseif ($default = \Context::get('_default_timezone'))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
elseif ($default = Config::get('locale.default_timezone'))
|
||||
{
|
||||
return $default;
|
||||
|
|
|
|||
|
|
@ -270,87 +270,92 @@ class Session
|
|||
* This method uses more or less the same logic as XE's SSO mechanism.
|
||||
* It may need to be changed to a more secure mechanism later.
|
||||
*
|
||||
* @return bool
|
||||
* @param object $site_module_info
|
||||
* @return void
|
||||
*/
|
||||
public static function checkSSO()
|
||||
public static function checkSSO($site_module_info)
|
||||
{
|
||||
// Abort if SSO is disabled, the visitor is a robot, or this is not a typical GET request.
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'GET' || !config('use_sso') || UA::isRobot() || in_array(\Context::get('act'), array('rss', 'atom')))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Abort of the default URL is not set.
|
||||
$default_url = \Context::getDefaultUrl();
|
||||
if (!$default_url)
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the current site information.
|
||||
$current_url = URL::getCurrentURL();
|
||||
$current_host = parse_url($current_url, \PHP_URL_HOST);
|
||||
$default_host = parse_url($default_url, \PHP_URL_HOST);
|
||||
$is_default_domain = ($site_module_info->domain_srl == 0);
|
||||
if (!$is_default_domain)
|
||||
{
|
||||
$current_domain = $site_module_info->domain;
|
||||
$current_url = URL::getCurrentUrl();
|
||||
$default_domain = getModel('module')->getDefaultDomainInfo();
|
||||
$default_url = \Context::getDefaultUrl($default_domain);
|
||||
}
|
||||
|
||||
// Step 1: if the current site is not the default site, send SSO validation request to the default site.
|
||||
if($default_host !== $current_host && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_host))
|
||||
if(!$is_default_domain && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_domain))
|
||||
{
|
||||
// Set sso cookie to prevent multiple simultaneous SSO validation requests.
|
||||
setcookie('sso', md5($current_host), 0, '/');
|
||||
setcookie('sso', md5($current_domain), 0, '/');
|
||||
|
||||
// Redirect to the default site.
|
||||
$sso_request = Security::encrypt($current_url);
|
||||
header('Location:' . URL::modifyURL($default_url, array('sso_request' => $sso_request)));
|
||||
return true;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Step 2: receive and process SSO validation request at the default site.
|
||||
if($default_host === $current_host && \Context::get('sso_request'))
|
||||
if($is_default_domain && \Context::get('sso_request'))
|
||||
{
|
||||
// Get the URL of the origin site
|
||||
$sso_request = Security::decrypt(\Context::get('sso_request'));
|
||||
if (!$sso_request || !preg_match('!^https?://!', $sso_request))
|
||||
{
|
||||
\Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400);
|
||||
return true;
|
||||
exit;
|
||||
}
|
||||
if (!URL::isInternalUrl($sso_request) || !Security::checkCSRF())
|
||||
{
|
||||
\Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Redirect back to the origin site.
|
||||
// Encrypt the session ID.
|
||||
self::start(true);
|
||||
$sso_response = Security::encrypt(session_id());
|
||||
|
||||
// Redirect back to the origin site.
|
||||
header('Location: ' . URL::modifyURL($sso_request, array('sso_response' => $sso_response)));
|
||||
return true;
|
||||
self::close();
|
||||
exit;
|
||||
}
|
||||
|
||||
// Step 3: back at the origin site, set session ID to be the same as the default site.
|
||||
if($default_host !== $current_host && \Context::get('sso_response'))
|
||||
if(!$is_default_domain && \Context::get('sso_response'))
|
||||
{
|
||||
// Check SSO response
|
||||
$sso_response = Security::decrypt(\Context::get('sso_response'));
|
||||
if ($sso_response === false)
|
||||
{
|
||||
\Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
|
||||
return true;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check that the response was given by the default site (to prevent session fixation CSRF).
|
||||
if(isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $default_url) !== 0)
|
||||
if(isset($_SERVER['HTTP_REFERER']) && strpos(URL::decodeIdna($_SERVER['HTTP_REFERER']), $default_url) !== 0)
|
||||
{
|
||||
\Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
|
||||
return true;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Set session ID.
|
||||
self::close();
|
||||
// Set the session ID.
|
||||
session_id($sso_response);
|
||||
self::start();
|
||||
self::start(true, false);
|
||||
|
||||
// Finally, redirect to the originally requested URL.
|
||||
header('Location: ' . URL::getCurrentURL(array('sso_response' => null)));
|
||||
return true;
|
||||
self::close();
|
||||
exit;
|
||||
}
|
||||
|
||||
// If none of the conditions above apply, proceed normally.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -456,6 +456,11 @@ class Storage
|
|||
return false;
|
||||
}
|
||||
|
||||
if (is_uploaded_file($source))
|
||||
{
|
||||
@chmod($destination, 0666 & ~self::getUmask());
|
||||
}
|
||||
|
||||
if (function_exists('opcache_invalidate'))
|
||||
{
|
||||
if (substr($source, -4) === '.php')
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class URL
|
|||
return true;
|
||||
}
|
||||
|
||||
if ($domain === self::getDomainFromURL(\Context::getDefaultUrl()))
|
||||
if (getModel('module')->getSiteInfoByDomain($domain))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1051,24 +1051,7 @@ function requirePear()
|
|||
*/
|
||||
function checkCSRF()
|
||||
{
|
||||
// Use Rhymix Security class first.
|
||||
if (Rhymix\Framework\Security::checkCSRF())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if we have a virtual site with a matching domain.
|
||||
$oModuleModel = getModel('module');
|
||||
$siteModuleInfo = $oModuleModel->getDefaultMid();
|
||||
$virtualSiteInfo = $oModuleModel->getSiteInfo($siteModuleInfo->site_srl);
|
||||
if (strcasecmp($virtualSiteInfo->domain, Context::get('vid')) && stristr($virtualSiteInfo->domain, $referer_host))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Rhymix\Framework\Security::checkCSRF();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -31,11 +31,10 @@ location ~ ^/rhymix/(.+)\.min\.(css|js)$ {
|
|||
# rss, blogAPI
|
||||
rewrite ^/rhymix/(rss|atom)$ /rhymix/index.php?module=rss&act=$1 last;
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/(rss|atom|api)$ /rhymix/index.php?mid=$1&act=$2 last;
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ /rhymix/index.php?vid=$1&mid=$2&act=$3 last;
|
||||
|
||||
# trackback
|
||||
rewrite ^/rhymix/([0-9]+)/(.+)/trackback$ /rhymix/index.php?document_srl=$1&key=$2&act=trackback last;
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /rhymix/index.php?vid=$1&document_srl=$2&key=$3&act=trackback last;
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /rhymix/index.php?mid=$1&document_srl=$2&key=$3&act=trackback last;
|
||||
|
||||
# administrator page
|
||||
rewrite ^/rhymix/admin/?$ /rhymix/index.php?module=admin last;
|
||||
|
|
@ -52,14 +51,5 @@ rewrite ^/rhymix/([a-zA-Z0-9_]+)/?$ /rhymix/index.php?mid=$1 last;
|
|||
# mid + document link
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)$ /rhymix/index.php?mid=$1&document_srl=$2 last;
|
||||
|
||||
# vid + mid link
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ /rhymix/index.php?vid=$1&mid=$2 last;
|
||||
|
||||
# vid + mid + document link
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ /rhymix/index.php?vid=$1&mid=$2&document_srl=$3 last;
|
||||
|
||||
# mid + entry title
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/entry/(.+)$ /rhymix/index.php?mid=$1&entry=$2 last;
|
||||
|
||||
# vid + mid + entry title
|
||||
rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ /rhymix/index.php?vid=$1&mid=$2&entry=$3 last;
|
||||
|
|
|
|||
|
|
@ -31,11 +31,10 @@ location ~ ^/(.+)\.min\.(css|js)$ {
|
|||
# rss, blogAPI
|
||||
rewrite ^/(rss|atom)$ /index.php?module=rss&act=$1 last;
|
||||
rewrite ^/([a-zA-Z0-9_]+)/(rss|atom|api)$ /index.php?mid=$1&act=$2 last;
|
||||
rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ /index.php?vid=$1&mid=$2&act=$3 last;
|
||||
|
||||
# trackback
|
||||
rewrite ^/([0-9]+)/(.+)/trackback$ /index.php?document_srl=$1&key=$2&act=trackback last;
|
||||
rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /index.php?vid=$1&document_srl=$2&key=$3&act=trackback last;
|
||||
rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /index.php?mid=$1&document_srl=$2&key=$3&act=trackback last;
|
||||
|
||||
# administrator page
|
||||
rewrite ^/admin/?$ /index.php?module=admin last;
|
||||
|
|
@ -52,14 +51,5 @@ rewrite ^/([a-zA-Z0-9_]+)/?$ /index.php?mid=$1 last;
|
|||
# mid + document link
|
||||
rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?mid=$1&document_srl=$2 last;
|
||||
|
||||
# vid + mid link
|
||||
rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ /index.php?vid=$1&mid=$2 last;
|
||||
|
||||
# vid + mid + document link
|
||||
rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?vid=$1&mid=$2&document_srl=$3 last;
|
||||
|
||||
# mid + entry title
|
||||
rewrite ^/([a-zA-Z0-9_]+)/entry/(.+)$ /index.php?mid=$1&entry=$2 last;
|
||||
|
||||
# vid + mid + entry title
|
||||
rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ /index.php?vid=$1&mid=$2&entry=$3 last;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
var https_port = {Context::get("_https_port") ?: 'null'};
|
||||
var enforce_ssl = {Context::get('_use_ssl') === 'always' ? 'true' : 'false'};
|
||||
var ssl_actions = {json_encode(array_keys(Context::getSSLActions()))};
|
||||
var xeVid = {json_encode($vid ?: null)};
|
||||
var xeVid = null;
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue