共享密钥系统容易受到 PHP 类型混淆(Type Juggling)攻击,攻击者可在不知道共享密钥的情况下访问日历内容。
要存在漏洞,必须启用日历共享密钥。

一旦启用此共享功能,用户即可通过共享密钥在无需认证的情况下访问日历。

当然,如果密钥错误,访问将被拒绝。
密钥验证位于文件“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';
}
}
strcmp 函数用于非严格比较。此比较的结果取决于以下内容:PHP 类型比较表
strcmp 函数的结果在文档中有说明:strcmp
如果 str1 小于 str2,则返回 < 0;如果 str1 大于 str2,则返回 > 0;如果两者相等,则返回 0。
如果其中一个参数是数组,该函数将返回“NULL”。
根据 PHP 类型比较表,“NULL”与 0 之间的非严格比较结果为 true
因此,如果 $_GET['cle'] 是一个数组,则条件结果为 true,访问被授权。
此链接会将 $_GET['cle'] 定义为数组: https://demo.soplanning.org/planning.php?public=1&cle[]=

访问将以“访客(Invité)”身份被授予。
要修复此漏洞,可以使用严格比较:
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';
}
}
或者,不使用 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';
}
}