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 '
+
+
';
}
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.