From 25f7b470a2ac7a1989850f10e0f0eaff70f064c6 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sat, 16 Nov 2019 12:47:04 -0800 Subject: [PATCH 1/9] Allow external redirects via the image proxy secret as a validation method. --- Sources/LogInOut.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sources/LogInOut.php b/Sources/LogInOut.php index 84cd1b8b90d..e7af908b97b 100644 --- a/Sources/LogInOut.php +++ b/Sources/LogInOut.php @@ -27,7 +27,7 @@ */ function Login() { - global $txt, $context, $scripturl, $user_info; + global $txt, $context, $scripturl, $user_info, $image_proxy_secret; // You are already logged in, go take a tour of the boards if (!empty($user_info['id'])) @@ -60,6 +60,9 @@ function Login() // Set the login URL - will be used when the login process is done (but careful not to send us to an attachment). if (isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) $_SESSION['login_url'] = $_SESSION['old_url']; + // This came from a valid hashed return url. Or something that knows our secrets... + elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) != $_REQUEST['return_hash']) + $_SESSION['login_url'] = urldecode($_REQUEST['return_to']); elseif (isset($_SESSION['login_url']) && strpos($_SESSION['login_url'], 'dlattach') !== false) unset($_SESSION['login_url']); @@ -145,7 +148,7 @@ function Login2() redirectexit(empty($user_settings['tfa_secret']) ? '' : 'action=logintfa'); elseif (!empty($_SESSION['login_url']) && (strpos($_SESSION['login_url'], 'http://') === false && strpos($_SESSION['login_url'], 'https://') === false)) { - unset ($_SESSION['login_url']); + unset($_SESSION['login_url']); redirectexit(empty($user_settings['tfa_secret']) ? '' : 'action=logintfa'); } elseif (!empty($user_settings['tfa_secret'])) From 4ca130edc64fcba7349f2c49009c383caf9b6d0a Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sat, 16 Nov 2019 13:17:17 -0800 Subject: [PATCH 2/9] Add the ability to confirm a logout by specifying logout with no session var. Ensuring that we can use redirects from outside SMF if needed. --- Sources/LogInOut.php | 25 ++++++++++++++++++- Themes/default/Login.template.php | 29 ++++++++++++++++++++++ Themes/default/languages/Login.english.php | 5 ++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/Sources/LogInOut.php b/Sources/LogInOut.php index e7af908b97b..2fa1c310eaf 100644 --- a/Sources/LogInOut.php +++ b/Sources/LogInOut.php @@ -648,8 +648,31 @@ function Logout($internal = false, $redirect = true) { global $sourcedir, $user_info, $user_settings, $context, $smcFunc, $cookiename, $modSettings; + // They decided to cancel a logout? + if (!$internal && isset($_POST['cancel']) && isset($_GET[$context['session_var']])) + redirectexit(!empty($_SESSION['logout_return']) ? $_SESSION['logout_return'] : ''); + // Prompt to logout? + elseif (!$internal && !isset($_GET[$context['session_var']])) + { + loadLanguage('Login'); + loadTemplate('Login'); + $context['sub_template'] = 'logout'; + + // This came from a valid hashed return url. Or something that knows our secrets... + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) != $_REQUEST['return_hash']) + { + $_SESSION['logout_url'] = urldecode($_REQUEST['return_to']); + $_SESSION['logout_return'] = $_SESSION['logout_url']; + } + // Setup the return address. + else + $_SESSION['logout_return'] = $_SESSION['old_url']; + + // Don't go any further. + return; + } // Make sure they aren't being auto-logged out. - if (!$internal) + elseif (!$internal && isset($_GET[$context['session_var']])) checkSession('get'); require_once($sourcedir . '/Subs-Auth.php'); diff --git a/Themes/default/Login.template.php b/Themes/default/Login.template.php index 1193f4a31e7..8e75ed4b970 100644 --- a/Themes/default/Login.template.php +++ b/Themes/default/Login.template.php @@ -448,4 +448,33 @@ function template_resend() '; } +/** + * Confirm a logout. + */ +function template_logout() +{ + global $context, $settings, $scripturl, $modSettings, $txt; + + // This isn't that much... just like normal login but with a message at the top. + echo ' +
+
+
+

', $txt['logout_confirm'], '

+
+
+

+ ', $txt['logout_notice'], ' +

+ +

+ + +

+ +

+
+ '; +} + ?> \ No newline at end of file diff --git a/Themes/default/languages/Login.english.php b/Themes/default/languages/Login.english.php index 72ce680b829..baa3f4ee700 100644 --- a/Themes/default/languages/Login.english.php +++ b/Themes/default/languages/Login.english.php @@ -140,4 +140,9 @@ $txt['registration_errors_occurred'] = 'The following errors were detected in your registration. Please correct them to continue:'; +// Logout +$txt['logout_confirm'] = 'Are you sure you want to log out?'; +$txt['logout_notice'] = 'You are about to be logged out of the forum and continue browsing as a guest?'; +$txt['logout_return'] = 'Stay logged in and return to browsing as a member.'; + ?> \ No newline at end of file From 353e58cea84e5055142ada98e69a1703de361344 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sat, 16 Nov 2019 13:25:05 -0800 Subject: [PATCH 3/9] Wrong Punctuation --- Themes/default/languages/Login.english.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Themes/default/languages/Login.english.php b/Themes/default/languages/Login.english.php index baa3f4ee700..46848bf623a 100644 --- a/Themes/default/languages/Login.english.php +++ b/Themes/default/languages/Login.english.php @@ -142,7 +142,7 @@ // Logout $txt['logout_confirm'] = 'Are you sure you want to log out?'; -$txt['logout_notice'] = 'You are about to be logged out of the forum and continue browsing as a guest?'; +$txt['logout_notice'] = 'You are about to be logged out of the forum and continue browsing as a guest!'; $txt['logout_return'] = 'Stay logged in and return to browsing as a member.'; ?> \ No newline at end of file From 9da5ec5f259410e1ae06f64be8c9c49e958dea44 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sat, 18 Jan 2020 08:11:15 -0800 Subject: [PATCH 4/9] Oops, thats bad --- Sources/LogInOut.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/LogInOut.php b/Sources/LogInOut.php index f0b9cb678a2..66c5b7b1651 100644 --- a/Sources/LogInOut.php +++ b/Sources/LogInOut.php @@ -61,7 +61,7 @@ function Login() if (isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) $_SESSION['login_url'] = $_SESSION['old_url']; // This came from a valid hashed return url. Or something that knows our secrets... - elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) != $_REQUEST['return_hash']) + elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) == $_REQUEST['return_hash']) $_SESSION['login_url'] = urldecode($_REQUEST['return_to']); elseif (isset($_SESSION['login_url']) && strpos($_SESSION['login_url'], 'dlattach') !== false) unset($_SESSION['login_url']); @@ -659,7 +659,7 @@ function Logout($internal = false, $redirect = true) $context['sub_template'] = 'logout'; // This came from a valid hashed return url. Or something that knows our secrets... - if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) != $_REQUEST['return_hash']) + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) == $_REQUEST['return_hash']) { $_SESSION['logout_url'] = urldecode($_REQUEST['return_to']); $_SESSION['logout_return'] = $_SESSION['logout_url']; From 505929c18b092a1303317e03aec29c20ca28d222 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sun, 19 Jan 2020 15:50:55 -0800 Subject: [PATCH 5/9] Use hmac_hash --- Sources/LogInOut.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/LogInOut.php b/Sources/LogInOut.php index 66c5b7b1651..e08fcec4820 100644 --- a/Sources/LogInOut.php +++ b/Sources/LogInOut.php @@ -61,7 +61,7 @@ function Login() if (isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) $_SESSION['login_url'] = $_SESSION['old_url']; // This came from a valid hashed return url. Or something that knows our secrets... - elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) == $_REQUEST['return_hash']) + elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', $_REQUEST['return_to'], $image_proxy_secret) == $_REQUEST['return_hash']) $_SESSION['login_url'] = urldecode($_REQUEST['return_to']); elseif (isset($_SESSION['login_url']) && strpos($_SESSION['login_url'], 'dlattach') !== false) unset($_SESSION['login_url']); @@ -659,7 +659,7 @@ function Logout($internal = false, $redirect = true) $context['sub_template'] = 'logout'; // This came from a valid hashed return url. Or something that knows our secrets... - if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && md5($_REQUEST['return_to'] . $image_proxy_secret) == $_REQUEST['return_hash']) + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', $_REQUEST['return_to'], $image_proxy_secret) == $_REQUEST['return_hash']) { $_SESSION['logout_url'] = urldecode($_REQUEST['return_to']); $_SESSION['logout_return'] = $_SESSION['logout_url']; From 4864c781cba7665ab9b0540004d30d5c99d805e1 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sun, 19 Jan 2020 15:53:39 -0800 Subject: [PATCH 6/9] Roundframe fix --- Themes/default/Login.template.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Themes/default/Login.template.php b/Themes/default/Login.template.php index f01adcbfcb7..7a750d6db58 100644 --- a/Themes/default/Login.template.php +++ b/Themes/default/Login.template.php @@ -471,8 +471,7 @@ function template_logout()

-
-

+ '; } From a85fd0d7b2ad666472f9de9a04888848c089b745 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sun, 25 Oct 2020 14:29:28 -0700 Subject: [PATCH 7/9] Fix a issue where url encoding can prevent the hash from matching If the member is logged in, we still want to redirect. --- Sources/LogInOut.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Sources/LogInOut.php b/Sources/LogInOut.php index 0fd1c570fc0..016a4de3d30 100644 --- a/Sources/LogInOut.php +++ b/Sources/LogInOut.php @@ -31,7 +31,13 @@ function Login() // You are already logged in, go take a tour of the boards if (!empty($user_info['id'])) - redirectexit(); + { + // This came from a valid hashed return url. Or something that knows our secrets... + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), $image_proxy_secret) == $_REQUEST['return_hash']) + redirectexit(base64_decode($_REQUEST['return_to'])); + else + redirectexit(); + } // We need to load the Login template/language file. loadLanguage('Login'); @@ -61,8 +67,8 @@ function Login() if (isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) $_SESSION['login_url'] = $_SESSION['old_url']; // This came from a valid hashed return url. Or something that knows our secrets... - elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', $_REQUEST['return_to'], $image_proxy_secret) == $_REQUEST['return_hash']) - $_SESSION['login_url'] = urldecode($_REQUEST['return_to']); + elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), $image_proxy_secret) == $_REQUEST['return_hash']) + $_SESSION['login_url'] = base64_decode($_REQUEST['return_to']); elseif (isset($_SESSION['login_url']) && strpos($_SESSION['login_url'], 'dlattach') !== false) unset($_SESSION['login_url']); @@ -676,7 +682,7 @@ function Logout($internal = false, $redirect = true) $context['sub_template'] = 'logout'; // This came from a valid hashed return url. Or something that knows our secrets... - if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', $_REQUEST['return_to'], $image_proxy_secret) == $_REQUEST['return_hash']) + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), $image_proxy_secret) == $_REQUEST['return_hash']) { $_SESSION['logout_url'] = urldecode($_REQUEST['return_to']); $_SESSION['logout_return'] = $_SESSION['logout_url']; From 794e4525c3d021e5cc474f912ba00227b86d1ef8 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sun, 25 Oct 2020 14:35:39 -0700 Subject: [PATCH 8/9] Use get_auth_secret() instead of $image_proxy_secret --- Sources/LogInOut.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/LogInOut.php b/Sources/LogInOut.php index 016a4de3d30..9d3e5a972f9 100644 --- a/Sources/LogInOut.php +++ b/Sources/LogInOut.php @@ -27,13 +27,13 @@ */ function Login() { - global $txt, $context, $scripturl, $user_info, $image_proxy_secret; + global $txt, $context, $scripturl, $user_info; // You are already logged in, go take a tour of the boards if (!empty($user_info['id'])) { // This came from a valid hashed return url. Or something that knows our secrets... - if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), $image_proxy_secret) == $_REQUEST['return_hash']) + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) redirectexit(base64_decode($_REQUEST['return_to'])); else redirectexit(); @@ -67,7 +67,7 @@ function Login() if (isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) $_SESSION['login_url'] = $_SESSION['old_url']; // This came from a valid hashed return url. Or something that knows our secrets... - elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), $image_proxy_secret) == $_REQUEST['return_hash']) + elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) $_SESSION['login_url'] = base64_decode($_REQUEST['return_to']); elseif (isset($_SESSION['login_url']) && strpos($_SESSION['login_url'], 'dlattach') !== false) unset($_SESSION['login_url']); @@ -682,7 +682,7 @@ function Logout($internal = false, $redirect = true) $context['sub_template'] = 'logout'; // This came from a valid hashed return url. Or something that knows our secrets... - if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), $image_proxy_secret) == $_REQUEST['return_hash']) + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) { $_SESSION['logout_url'] = urldecode($_REQUEST['return_to']); $_SESSION['logout_return'] = $_SESSION['logout_url']; From c1d1550c1790d1a7d8510286b011a404266e9221 Mon Sep 17 00:00:00 2001 From: jdarwood007 Date: Sat, 6 Mar 2021 11:41:05 -0800 Subject: [PATCH 9/9] Do not use base64 for urls --- Sources/LogInOut.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/LogInOut.php b/Sources/LogInOut.php index 3b8ae30cc2c..4c15456bf57 100644 --- a/Sources/LogInOut.php +++ b/Sources/LogInOut.php @@ -33,8 +33,8 @@ function Login() if (!empty($user_info['id'])) { // This came from a valid hashed return url. Or something that knows our secrets... - if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) - redirectexit(base64_decode($_REQUEST['return_to'])); + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', un_htmlspecialchars($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) + redirectexit(un_htmlspecialchars($_REQUEST['return_to'])); else redirectexit(); } @@ -67,8 +67,8 @@ function Login() if (isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) $_SESSION['login_url'] = $_SESSION['old_url']; // This came from a valid hashed return url. Or something that knows our secrets... - elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) - $_SESSION['login_url'] = base64_decode($_REQUEST['return_to']); + elseif (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', un_htmlspecialchars($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) + $_SESSION['login_url'] = un_htmlspecialchars($_REQUEST['return_to']); elseif (isset($_SESSION['login_url']) && strpos($_SESSION['login_url'], 'dlattach') !== false) unset($_SESSION['login_url']); @@ -685,9 +685,9 @@ function Logout($internal = false, $redirect = true) $context['sub_template'] = 'logout'; // This came from a valid hashed return url. Or something that knows our secrets... - if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', base64_decode($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) + if (!empty($_REQUEST['return_hash']) && !empty($_REQUEST['return_to']) && hash_hmac('sha1', un_htmlspecialchars($_REQUEST['return_to']), get_auth_secret()) == $_REQUEST['return_hash']) { - $_SESSION['logout_url'] = urldecode($_REQUEST['return_to']); + $_SESSION['logout_url'] = un_htmlspecialchars($_REQUEST['return_to']); $_SESSION['logout_return'] = $_SESSION['logout_url']; } // Setup the return address.