Add CSRF protection to every form that changes data.

The logout link carries the token too, and the cookies get SameSite=Lax.
This commit is contained in:
tim
2026-09-25 21:38:22 +02:00
parent f6bdf10228
commit 41c46a43c6
9 changed files with 53 additions and 5 deletions
+24 -3
View File
@@ -6,7 +6,7 @@ $is_admin = FALSE;
if (isset($_SERVER['HTTPS'])) {
session_cache_limiter('private');
session_set_cookie_params(strtotime('+1 year'), '/', '.xxx.org.za', TRUE, TRUE);
session_set_cookie_params(array('lifetime' => strtotime('+1 year'), 'path' => '/', 'domain' => '.xxx.org.za', 'secure' => TRUE, 'httponly' => TRUE, 'samesite' => 'Lax'));
session_start();
if (isset($_SESSION['editor'])) {
@@ -72,7 +72,7 @@ function create_persistent_login($username) {
open_db('close');
// Create cookie with key
setcookie('PersistentAuth', "$username|$key", $validity, '/', '.xxx.org.za', TRUE, TRUE);
setcookie('PersistentAuth', "$username|$key", array('expires' => $validity, 'path' => '/', 'domain' => '.xxx.org.za', 'secure' => TRUE, 'httponly' => TRUE, 'samesite' => 'Lax'));
return true;
}
@@ -97,7 +97,28 @@ function delete_persistent_login() {
open_db('close');
// Delete cookie
setcookie("PersistentAuth", false, strtotime('-1 year'), '/', '.xxx.org.za', TRUE, TRUE);
setcookie("PersistentAuth", '', array('expires' => strtotime('-1 year'), 'path' => '/', 'domain' => '.xxx.org.za', 'secure' => TRUE, 'httponly' => TRUE, 'samesite' => 'Lax'));
return true;
}
/*
* CSRF protection: every form that changes something carries a random
* token from the session, and the handler checks it before acting.
*/
function csrf_token() {
if (empty($_SESSION['csrf_token']) || !is_string($_SESSION['csrf_token']))
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
return $_SESSION['csrf_token'];
}
function csrf_field() {
return '<input type="hidden" name="csrf_token" value="'.csrf_token().'" />';
}
function csrf_valid($token = NULL) {
if ($token === NULL)
$token = $_POST['csrf_token'] ?? '';
return is_string($token) && isset($_SESSION['csrf_token']) &&
hash_equals((string)$_SESSION['csrf_token'], $token);
}