perf : session lazy + CSRF cookie + 410 DokuWiki
Contexte : sur abonnel.fr, session_start() était appelé sur chaque
requête PHP (y compris bots), créant ~17 000 fichiers de session/jour
dans un répertoire custom non nettoyé par le cron Debian. Les workers
PHP-FPM grossissaient en mémoire et le pool saturait (1 188 erreurs
503 en 30 minutes).
Changements :
public/index.php
- session_start() uniquement si le cookie de session existe déjà ou si
la requête est POST. Les bots (GET sans cookie) ne créent plus de
session.
- CSRF commentaires migré de $_SESSION['comment_csrf'] vers un double-
submit cookie (_csrf_c, SameSite=Strict, HttpOnly). La session n'est
plus requise pour les visiteurs anonymes qui postent un commentaire.
templates/comments_section.php
- Génère le token CSRF et le pose en cookie (_csrf_c) au lieu de
l'écrire en session.
public/.htaccess
- Règle Apache 410 Gone pour toute URL contenant un paramètre ?do=
(anciens paramètres DokuWiki : do=media, do=export_pdf…). Traité par
Apache en 2ms sans toucher PHP-FPM.
public/oidc/{start,callback,me}.php
- Correction du bug introduit par 0b8077e : config.php (qui utilise
BASE_PATH) était chargé avant bootstrap.php (qui définit BASE_PATH).
Fix : define('BASE_PATH', …) ajouté avant le require config.php.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,10 @@ DirectoryIndex index.php
|
|||||||
|
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
|
|
||||||
|
# Paramètres DokuWiki (?do=media, ?do=export_pdf, etc.) — 410 Gone, jamais de contenu ici
|
||||||
|
RewriteCond %{QUERY_STRING} (^|&)do= [NC]
|
||||||
|
RewriteRule ^ - [R=410,L]
|
||||||
|
|
||||||
# Fichiers et répertoires réels servis directement
|
# Fichiers et répertoires réels servis directement
|
||||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||||||
RewriteCond %{REQUEST_FILENAME} -d
|
RewriteCond %{REQUEST_FILENAME} -d
|
||||||
|
|||||||
+10
-5
@@ -4,11 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
define('BASE_PATH', realpath(__DIR__ . '/../'));
|
define('BASE_PATH', realpath(__DIR__ . '/../'));
|
||||||
|
|
||||||
if (session_status() === PHP_SESSION_NONE) {
|
$_sessionName = getenv('SESSION_NAME') ?: 'PHPSESSID';
|
||||||
|
if (session_status() === PHP_SESSION_NONE
|
||||||
|
&& (isset($_COOKIE[$_sessionName]) || $_SERVER['REQUEST_METHOD'] === 'POST')
|
||||||
|
) {
|
||||||
$isHttps = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
|
$isHttps = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
|
||||||
|
session_name($_sessionName);
|
||||||
session_set_cookie_params(['lifetime' => 0, 'path' => '/', 'secure' => $isHttps, 'httponly' => true, 'samesite' => 'Lax']);
|
session_set_cookie_params(['lifetime' => 0, 'path' => '/', 'secure' => $isHttps, 'httponly' => true, 'samesite' => 'Lax']);
|
||||||
session_start();
|
session_start();
|
||||||
}
|
}
|
||||||
|
unset($_sessionName);
|
||||||
|
|
||||||
require_once BASE_PATH . '/src/helpers.php';
|
require_once BASE_PATH . '/src/helpers.php';
|
||||||
require_once BASE_PATH . '/src/auth.php';
|
require_once BASE_PATH . '/src/auth.php';
|
||||||
@@ -1888,10 +1893,10 @@ switch ($action) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CSRF
|
// CSRF (double-submit cookie — pas de session requise pour les visiteurs)
|
||||||
$csrfOk = isset($_POST['_token'], $_SESSION['comment_csrf'])
|
$csrfOk = isset($_POST['_token'], $_COOKIE['_csrf_c'])
|
||||||
&& hash_equals($_SESSION['comment_csrf'], $_POST['_token']);
|
&& hash_equals($_COOKIE['_csrf_c'], $_POST['_token']);
|
||||||
unset($_SESSION['comment_csrf']);
|
setcookie('_csrf_c', '', ['expires' => time() - 3600, 'path' => '/', 'samesite' => 'Strict', 'httponly' => true]);
|
||||||
if (!$csrfOk) {
|
if (!$csrfOk) {
|
||||||
header('Location: /');
|
header('Location: /');
|
||||||
exit;
|
exit;
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
if (!defined('BASE_PATH')) {
|
||||||
|
define('BASE_PATH', dirname(__DIR__, 2));
|
||||||
|
}
|
||||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
require_once dirname(__DIR__, 2) . '/config/config.php';
|
require_once dirname(__DIR__, 2) . '/config/config.php';
|
||||||
require_once dirname(__DIR__, 2) . '/bootstrap.php';
|
require_once dirname(__DIR__, 2) . '/bootstrap.php';
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
// version : 20251005
|
// version : 20251005
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
if (!defined('BASE_PATH')) {
|
||||||
|
define('BASE_PATH', dirname(__DIR__, 2));
|
||||||
|
}
|
||||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
require_once dirname(__DIR__, 2) . '/config/config.php';
|
require_once dirname(__DIR__, 2) . '/config/config.php';
|
||||||
require_once dirname(__DIR__, 2) . '/bootstrap.php';
|
require_once dirname(__DIR__, 2) . '/bootstrap.php';
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
if (!defined('BASE_PATH')) {
|
||||||
|
define('BASE_PATH', dirname(__DIR__, 2));
|
||||||
|
}
|
||||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
require_once dirname(__DIR__, 2) . '/config/config.php';
|
require_once dirname(__DIR__, 2) . '/config/config.php';
|
||||||
require_once dirname(__DIR__, 2) . '/bootstrap.php';
|
require_once dirname(__DIR__, 2) . '/bootstrap.php';
|
||||||
|
|||||||
@@ -15,7 +15,13 @@ $_reactionDefs = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
$_csrfToken = bin2hex(random_bytes(16));
|
$_csrfToken = bin2hex(random_bytes(16));
|
||||||
$_SESSION['comment_csrf'] = $_csrfToken;
|
setcookie('_csrf_c', $_csrfToken, [
|
||||||
|
'expires' => 0,
|
||||||
|
'path' => '/',
|
||||||
|
'secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off',
|
||||||
|
'httponly' => true,
|
||||||
|
'samesite' => 'Strict',
|
||||||
|
]);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<?php if (!empty($alsoReadArticles ?? [])): ?>
|
<?php if (!empty($alsoReadArticles ?? [])): ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user