
Preuve de concept d'exploit pour CVE-2020-25867 démontrant le contournement de l'authentification par clé de partage de calendrier de SoPlanning via le PHP type juggling.
Le système de clé de partage est vulnérable à une attaque de type PHP Type Juggling, qui permet à un attaquant d'accéder au contenu du calendrier sans connaître la clé de partage.
Pour être vulnérable, la clé de partage du calendrier doit être activée.

Une fois ce partage activé, un utilisateur peut accéder au calendrier sans authentification en utilisant la clé de partage.

Bien sûr, si la clé est fausse, l'accès est refusé.
La validation de la clé se trouve dans le fichier "includes/header.inc"
if ( CONFIG_SOPLANNING_OPTION_ACCES == 2 && isset($_GET['public']) && isset($_GET['cle']))
{
if (strcmp($_GET['cle'],CONFIG_SECURE_KEY)==0)
{
$_SESSION['public']=1;
$_SESSION['user_id']='publicspl';
}
}
La fonction strcmp est utilisée avec une comparaison non stricte. Le résultat de cette comparaison dépend de ce qui suit : Tableaux de comparaison de types PHP
Le résultat de la fonction strcmp est décrit dans la documentation : [strcmp]'https://www.php.net/manual/en/function.strcmp.php)
Retourne < 0 si str1 est inférieur à str2 ; > 0 si str1 est supérieur à str2, et 0 s'ils sont égaux.
Cette fonction retourne "NULL" si l'un des paramètres est un tableau.
D'après les Tableaux de comparaison de types PHP, la comparaison non stricte entre "NULL" et 0 est true
Ainsi, si $_GET['cle'] est un tableau, le résultat de la condition est true et l'accès est autorisé.
Ce lien définira $_GET['cle'] comme un tableau : https://demo.soplanning.org/planning.php?public=1&cle[]=

L'accès est accordé en tant que "Invité"
Pour corriger cette vulnérabilité, une comparaison stricte peut être utilisée :
if ( CONFIG_SOPLANNING_OPTION_ACCES == 2 && isset($_GET['public']) && isset($_GET['cle']))
{
if (strcmp($_GET['cle'],CONFIG_SECURE_KEY)===0)
{
$_SESSION['public']=1;
$_SESSION['user_id']='publicspl';
}
}
Ou la comparaison peut être effectuée sans la fonction strcmp.
if ( CONFIG_SOPLANNING_OPTION_ACCES == 2 && isset($_GET['public']) && isset($_GET['cle']))
{
if ($_GET['cle'] === CONFIG_SECURE_KEY)
{
$_SESSION['public']=1;
$_SESSION['user_id']='publicspl';
}
}