diff --git a/data/web/admin.php b/data/web/admin.php index 384e20da..e3f978f0 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -351,6 +351,7 @@ $tfa_data = get_tfa(); diff --git a/data/web/inc/footer.inc.php b/data/web/inc/footer.inc.php index 05b7a599..605a4e7c 100644 --- a/data/web/inc/footer.inc.php +++ b/data/web/inc/footer.inc.php @@ -225,6 +225,7 @@ $(document).ready(function() { } }); }); + $("' />").attr("id", "csrf_token").attr("name", "csrf_token").appendTo("form"); }); diff --git a/data/web/inc/sessions.inc.php b/data/web/inc/sessions.inc.php index b6241839..1b2c986c 100644 --- a/data/web/inc/sessions.inc.php +++ b/data/web/inc/sessions.inc.php @@ -15,21 +15,8 @@ else { } session_set_cookie_params($GLOBALS['SESSION_LIFETIME'], '/', $_SERVER['SERVER_NAME'], $IS_HTTPS, true); session_start(); - -// Handle logouts -if (isset($_POST["logout"])) { - if (isset($_SESSION["dual-login"])) { - $_SESSION["mailcow_cc_username"] = $_SESSION["dual-login"]["username"]; - $_SESSION["mailcow_cc_role"] = $_SESSION["dual-login"]["role"]; - unset($_SESSION["dual-login"]); - } - else { - session_regenerate_id(true); - session_unset(); - session_destroy(); - session_write_close(); - header("Location: /"); - } +if (!isset($_SESSION['CSRF']['TOKEN'])) { + $_SESSION['CSRF']['TOKEN'] = bin2hex(random_bytes(32)); } // Set session IP and UA @@ -51,12 +38,36 @@ function session_check() { if ($_SESSION['SESS_REMOTE_UA'] != $_SERVER['HTTP_USER_AGENT']) { return false; } + if (!empty($_POST)) { + if ($_SESSION['CSRF']['TOKEN'] != $_POST['csrf_token']) { + return false; + } + $_SESSION['CSRF']['TOKEN'] = bin2hex(random_bytes(32)); + $_SESSION['CSRF']['TIME'] = time(); + } return true; } + if (isset($_SESSION['mailcow_cc_role']) && session_check() === false) { - session_regenerate_id(true); - session_unset(); - session_destroy(); - session_write_close(); - header("Location: /"); + $_SESSION['return'] = array( + 'type' => 'warning', + 'msg' => 'Form token invalid or timed out' + ); + $_POST = array(); } + +// Handle logouts +if (isset($_POST["logout"])) { + if (isset($_SESSION["dual-login"])) { + $_SESSION["mailcow_cc_username"] = $_SESSION["dual-login"]["username"]; + $_SESSION["mailcow_cc_role"] = $_SESSION["dual-login"]["role"]; + unset($_SESSION["dual-login"]); + } + else { + session_regenerate_id(true); + session_unset(); + session_destroy(); + session_write_close(); + header("Location: /"); + } +} \ No newline at end of file diff --git a/data/web/js/admin.js b/data/web/js/admin.js index 96c189be..711070dd 100644 --- a/data/web/js/admin.js +++ b/data/web/js/admin.js @@ -52,7 +52,7 @@ $(document).ready(function() { $.ajax({ type: "POST", dataType: "json", - data: { "items": JSON.stringify(data_array) }, + data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token }, url: '/api/v1/' + api_url, jsonp: false, complete: function (data) { diff --git a/data/web/js/mailbox.js b/data/web/js/mailbox.js index 5bd9a64e..bd802fe9 100644 --- a/data/web/js/mailbox.js +++ b/data/web/js/mailbox.js @@ -43,7 +43,7 @@ $(document).ready(function() { $.ajax({ type: "POST", dataType: "json", - data: { "items": JSON.stringify(data_array), "attr": JSON.stringify(api_attr) }, + data: { "items": JSON.stringify(data_array), "attr": JSON.stringify(api_attr), "csrf_token": csrf_token }, url: '/api/v1/' + api_url, jsonp: false, complete: function (data) { @@ -76,7 +76,7 @@ $(document).ready(function() { $.ajax({ type: "POST", dataType: "json", - data: { "items": JSON.stringify(data_array) }, + data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token }, url: '/api/v1/' + api_url, jsonp: false, complete: function (data) { diff --git a/data/web/mailbox.php b/data/web/mailbox.php index 6853a9d9..b04ae968 100644 --- a/data/web/mailbox.php +++ b/data/web/mailbox.php @@ -172,6 +172,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];