Closed sudwebdesign closed 10 months ago
PluXml dans sa version actuelle ne permet pas de faire tourner 2 instances de PluXml sur le même serveur dans des dossiers différents. Il faut modifier la gestion des cookies pour prendre en compte ces dossiers Modifier danscore/lib/config.php lafonction plx_session_start() comme suit :
function plx_session_start() {
$params = [
'cookie_path' => preg_replace('#/\w[\w-]+\.php$#', '/', $_SERVER['PHP_SELF']),
'cookie_secure' => isset($_SERVER['HTTPS']),
'cookie_httponly' => true,
'cookie_samesite' => 'strict',
];
if (!defined('PLX_AUTH') and defined('SESSION_LIFETIME')) {
$params['gc_maxlifetime'] = SESSION_LIFETIME;
}
if (!session_start($params)) {
header('Content-Type: Text/Plain; charset=utf-8');
echo 'Internal error! Goodbye';
exit;
};
}
Si on ouvre la console de déboggage de Firefox, on vérifie bien qu'il y a des cookies de session différents pour chaque dossier. Je vais lire la doc de PHP pour pousser les investigations plus loin en terme de sécurité
Comme écrit juste après (dans le code ligne 13 de prepend.php), il est juste pour les pages admins :
# Si utilisateur désactivé ou supprimé par un admin, hors page de login. (!PLX_AUTHPAGE)
c'est un vieux bogue dù a un oubli de mon PR de l'époque AdminPrepend : Disconnect or modify user profile in live #338 Un explicatif :
En ayant une session active sur l'un (plx587 user 002 par exemple) et en voulant jouer sur un autre onglet ouvert (plx589 qui a 1 seul user), il redirige vers auth.php?p=' . htmlentities($_SERVER['REQUEST_URI']
(c'est bien) car $_SESSION['domain'] != SESSION_DOMAIN
et arrivé à la page auth.php?p=
qui inclut prepend.php
qui; lui; va appliquer la règle et rediriger vers auth.php?d=1
de manière perpétuelle car il ne sait pas qu'il y est... Et que la déconnexion se fait après.
C'est sur qu'il manque le AND !defined('PLX_AUTHPAGE')
avec ça, cela déconnecte bien et affiche la page de login
Voici un vieux code que j'utilise et qui explique mieux que mille mots:
if(defined('PLX_AUTHPAGE')) {
$lang = PLX_SITE_LANG;
} else {
# Si désactivé ou supprimé par un admin, hors page de login. (!PLX_AUTHPAGE)
if(empty($_SESSION['user']) OR !$plxAdmin->aUsers[$_SESSION['user']]['active'] OR $plxAdmin->aUsers[$_SESSION['user']]['delete']) {
header('Location: auth.php?d=1');# Déconnecte l'utilisateur a la prochaine demande,
exit;
}
# Détermination de la langue à utiliser (modifiable par le hook AdminPrepend)
$lang = $plxAdmin->aUsers[$_SESSION['user']]['lang'];
# Donne ou change le Profil d'utilisateur dès sa prochaine action, hors page de login. (!PLX_AUTHPAGE)
if(!isset($_SESSION['profil']) OR $_SESSION['profil'] != $plxAdmin->aUsers[$_SESSION['user']]['profil'])
$_SESSION['profil'] = $plxAdmin->aUsers[$_SESSION['user']]['profil'];
}
Il y a aussi la possibilité de remonter "la déconnexion" au dessus de include prepend.php
ds auth.php
Merci de la réponse, maintenant je sais où est plx_session_start, a vrai dire je l'avais vu mais pas cherchés et longue vie a #PluXml :)
Ps: En aucune raison c'est pour avoir une session pour plusieurs PluXml, les anciens le faisaient et parfois s'emmelaient les pinceaux, pardon les sessions...
Le problème ne vient pas qu'il manque _AND !defined('PLXAUTHPAGE') mais que le paramètre path dans plx_session_start() est faux. Sa valeur est une url au lieu du chemin demandé dans la requête HTTP. De plus, on suppose que PluXml est installé à la racine du site ce qui n'est pas forcément le cas. Ta remarque évite juste une éventuelle boucle sur auth.php mais n'empêche pas les déconnexions intempestives des 2 instances de PluXml. On peut vérifier la bonne gestion des cookies de session dans l'explorateur de code de Firefox (touche F12) et dans l'onglet stockage.
Autre remarque sans rapport avec le sujet : La constante SESSION_LIFETIME n'a aucun effet car sa valeur ( 2 heures) est plus grande que celle précisée dans le php.ini du moteur PHP (24 minutes)
Pour éviter de boucler indéfiniment quand on se déconnecte, il vaut mieux définir une constante de redirection dans auth.php :
const DEL_USER_QUERY = 'auth.php?d=1';
# .....
if(
isset($_SESSION['user']) and
!preg_match('#\b' . DEL_USER_QUERY . '$#', $_SERVER['REQUEST_URI']) // for avoiding infinite loops
) {
# Si utilisateur désactivé ou supprimé par un admin, hors page de login. (!PLX_AUTHPAGE)
if(
!array_key_exists($_SESSION['user'], $plxAdmin->aUsers) or
empty($plxAdmin->aUsers[$_SESSION['user']]['active']) or
!empty($plxAdmin->aUsers[$_SESSION['user']]['delete'])
) {
header('Location: ' . DEL_USER_QUERY);# Déconnecte l'utilisateur a la prochaine demande,
exit;
} else {
$lang = $plxAdmin->aUsers[$_SESSION['user']]['lang'];
$_SESSION['profil'] = $plxAdmin->aUsers[$_SESSION['user']]['profil'];
}
}
Je vais faire un pull request (PR) pour corriger ces problèmes de session.
Merci de la solution #686 mais dans l'état ça continue de boucler sur auth.
Après quelques recherches et tests, a la ligne 8 le point d'interrogation n'est pas échappé.
Avec const DEL_USER_QUERY = 'auth.php\?d=1';
tout roule ;)
Si je comprend bien, fini les déconnexions intempestives entre Pluxml qui sont sur le même serveur dans des dossiers différents :100: :1st_place_medal: Je continue les tests...
Je suis allés vite en besogne, maintenant avec cette solution, lorsque je me connecte :
localhost/pluxml/core/admin/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/auth.php/?d=1
Le navigateur dit La page n’est pas redirigée correctement
Donc pire qu'avant :(
Maintenant avec DEL_USER_REGEX ça roule.
Effectivement le caractère '?' de est mal interprété par preg_match(). Plutôt que de créer une nouvelle constante, on peut utiliser addcslashes() qui permet de préciser les caractères à échapper. Mais cette redirection ne me plait pas. On informe l'attaquant qu'il y a redirection. Je préfère une solution plus radicale. On crée une fonction log_out() dans prepend.php qui reprend le bloc de code de auth.php qui traite la requête ?d=1. Ainsi on peut l'appeler dans prepend.php si on ne trouve pas l'utilisateur déclaré dans $_SESSION et on économise une redirection Voir PR https://github.com/pluxml/PluXml/pull/687
@bazooka07 C'est clair, les 2 constantes était pour un exemple fonctionnel :) Et le PR#687 est une solution bien plus sure et plus subtile :+1:
Pour reproduire : En local et aucun hôte virtuel avec 2 instances de PluXml comme localhost/plx1 ET localhost/plx2 1-Se connecter a plx1 avec un utilisateur inexistant/supprimé au plx2 (important) 2-nouvel onglet, aller a localhost/plx2/core/admin/ Résultat "La page n’est pas redirigée correctement" Il boucle sur auth.php?d=1
Se code me rappelle quelque chose :)