Skip to content

Commit

Permalink
Fixes #5297: Improve error message in cases of suspected cross-domain…
Browse files Browse the repository at this point in the history
… login
  • Loading branch information
mrclay committed Apr 1, 2013
1 parent 835c7fe commit a4874cb
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 23 deletions.
73 changes: 50 additions & 23 deletions engine/lib/actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ function action($action, $forwarder = "") {
);

if (!in_array($action, $exceptions)) {
// All actions require a token.
action_gatekeeper();
action_gatekeeper($action);
}

$forwarder = str_replace(elgg_get_site_url(), "", $forwarder);
Expand Down Expand Up @@ -187,6 +186,26 @@ function elgg_unregister_action($action) {
}
}

/**
* Is the token timestamp within acceptable range?
*
* @param int $ts timestamp from the CSRF token
*
* @return bool
*/
function _elgg_validate_token_timestamp($ts) {
$action_token_timeout = elgg_get_config('action_token_timeout');
// default is 2 hours
$timeout = ($action_token_timeout !== null) ? $action_token_timeout : 2;

$hour = 60 * 60;
$timeout = $timeout * $hour;
$now = time();

// Validate time to ensure its not crazy
return ($timeout == 0 || ($ts > $now - $timeout) && ($ts < $now + $timeout));
}

/**
* Validate an action token.
*
Expand All @@ -205,8 +224,6 @@ function elgg_unregister_action($action) {
* @access private
*/
function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL) {
global $CONFIG;

if (!$token) {
$token = get_input('__elgg_token');
}
Expand All @@ -215,29 +232,18 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)
$ts = get_input('__elgg_ts');
}

if (!isset($CONFIG->action_token_timeout)) {
// default to 2 hours
$timeout = 2;
} else {
$timeout = $CONFIG->action_token_timeout;
}

$session_id = session_id();

if (($token) && ($ts) && ($session_id)) {
// generate token, check with input and forward if invalid
$generated_token = generate_action_token($ts);
$required_token = generate_action_token($ts);

// Validate token
if ($token == $generated_token) {
$hour = 60 * 60;
$timeout = $timeout * $hour;
$now = time();

// Validate time to ensure its not crazy
if ($timeout == 0 || ($ts > $now - $timeout) && ($ts < $now + $timeout)) {
if ($token == $required_token) {

if (_elgg_validate_token_timestamp($ts)) {
// We have already got this far, so unless anything
// else says something to the contry we assume we're ok
// else says something to the contrary we assume we're ok
$returnval = true;

$returnval = elgg_trigger_plugin_hook('action_gatekeeper:permissions:check', 'all', array(
Expand Down Expand Up @@ -293,12 +299,33 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)
* This function verifies form input for security features (like a generated token),
* and forwards if they are invalid.
*
* @param string $action The action being performed
*
* @return mixed True if valid or redirects.
* @access private
*/
function action_gatekeeper() {
if (validate_action_token()) {
return TRUE;
function action_gatekeeper($action) {
if ($action === 'login') {
if (validate_action_token(false)) {
return true;
}

$token = get_input('__elgg_token');
$ts = (int)get_input('__elgg_ts');
if ($token && _elgg_validate_token_timestamp($ts)) {
// The tokens are present and the time looks valid: this is probably a mismatch due to the
// login form being on a different domain.
register_error(elgg_echo('actiongatekeeper:crosssitelogin'));


forward('login', 'csrf');
}

// let the validator send an appropriate msg
validate_action_token();

} elseif (validate_action_token()) {
return true;
}

forward(REFERER, 'csrf');
Expand Down
8 changes: 8 additions & 0 deletions htaccess_dist
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ RewriteEngine on
#
#RewriteBase /


# If your users receive the message "Sorry, logging in from a different domain is not permitted"
# you must make sure your login form is served from the same hostname as your site pages.
# See http://docs.elgg.org/wiki/Login_token_mismatch_error for more info.
#
# If you must add RewriteRules to change hostname, add them directly below (above all the others)


# In for backwards compatibility
RewriteRule ^pg\/([A-Za-z0-9\_\-]+)$ engine/handlers/page_handler.php?handler=$1&%{QUERY_STRING} [L]
RewriteRule ^pg\/([A-Za-z0-9\_\-]+)\/(.*)$ engine/handlers/page_handler.php?handler=$1&page=$2&%{QUERY_STRING} [L]
Expand Down
1 change: 1 addition & 0 deletions languages/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,7 @@
'actiongatekeeper:timeerror' => 'The page you were using has expired. Please refresh and try again.',
'actiongatekeeper:pluginprevents' => 'A extension has prevented this form from being submitted.',
'actiongatekeeper:uploadexceeded' => 'The size of file(s) uploaded exceeded the limit set by your site administrator',
'actiongatekeeper:crosssitelogin' => "Sorry, logging in from a different domain is not permitted.",


/**
Expand Down

0 comments on commit a4874cb

Please sign in to comment.