diff options
author | Silvio Rhatto <rhatto@riseup.net> | 2014-03-14 21:25:01 -0300 |
---|---|---|
committer | Silvio Rhatto <rhatto@riseup.net> | 2014-03-14 21:25:01 -0300 |
commit | 3651c99a195685f3a868e159e72c4daf8cb371d3 (patch) | |
tree | cb004dd7b6ca55215a2c20112fe0c5209d98c18e /engine/lib/actions.php | |
parent | 97e689213ff4e829f251af526ed4e796a3cc2b71 (diff) | |
parent | c2707bb867ddb285af85d7a0e75db26ef692d68c (diff) | |
download | elgg-3651c99a195685f3a868e159e72c4daf8cb371d3.tar.gz elgg-3651c99a195685f3a868e159e72c4daf8cb371d3.tar.bz2 |
Merge branch 'master' into saravea
Conflicts:
mod/blog/views/default/blog/sidebar/archives.php
Diffstat (limited to 'engine/lib/actions.php')
-rw-r--r-- | engine/lib/actions.php | 100 |
1 files changed, 75 insertions, 25 deletions
diff --git a/engine/lib/actions.php b/engine/lib/actions.php index f78ca63df..8047914ac 100644 --- a/engine/lib/actions.php +++ b/engine/lib/actions.php @@ -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); @@ -188,6 +187,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. * * Calls to actions will automatically validate tokens. If tokens are not @@ -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'); } @@ -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( @@ -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'); @@ -337,16 +364,19 @@ function generate_action_token($timestamp) { } /** - * Initialise the site secret hash. + * Initialise the site secret (32 bytes: "z" to indicate format + 186-bit key in Base64 URL). * * Used during installation and saves as a datalist. * + * Note: Old secrets were hex encoded. + * * @return mixed The site secret hash or false * @access private * @todo Move to better file. */ function init_site_secret() { - $secret = md5(rand() . microtime()); + $secret = 'z' . ElggCrypto::getRandomString(31); + if (datalist_set('__site_secret__', $secret)) { return $secret; } @@ -373,6 +403,26 @@ function get_site_secret() { } /** + * Get the strength of the site secret + * + * @return string "strong", "moderate", or "weak" + * @access private + */ +function _elgg_get_site_secret_strength() { + $secret = get_site_secret(); + if ($secret[0] !== 'z') { + $rand_max = getrandmax(); + if ($rand_max < pow(2, 16)) { + return 'weak'; + } + if ($rand_max < pow(2, 32)) { + return 'moderate'; + } + } + return 'strong'; +} + +/** * Check if an action is registered and its script exists. * * @param string $action Action name |