防止 "ssi_function=something" 绕过正常的控制流
Prevent "ssi_function=something" from bypassing normal control flow
如果您熟悉 SMF,这就是您通常使用其服务器端的方式,包括:
//foo.php at http://example/foo.php
<?php
require('./SSI.php'); //assuming we're at SMF's root
//...
?>
但对于未经训练的人来说,访问 http://example/foo.php?ssi_function=something
will cause ssi_something
to be called inside SSI.php
是隐藏的,有效地绕过了 foo.php
的正常行为。
我可以在 require
之前添加这个,但我可以避免重定向:
if(isset($_GET['ssi_function']))
{
unset($_GET['ssi_function']);
return header('Location: ?' . http_build_query($_GET));
}
我已经打开了 issue on GitHub,但是我还有什么其他选择可以解决这个问题?
正如您所提到的,这是 SMF 中依赖于实现的行为。在这种情况下,您不需要进行重定向,因为 $_GET
超全局变量是可变的,只需删除 ssi_function
参数就足够了。
此错误已在 #4038 中修复。
@@ -177,6 +177,9 @@
// Have the ability to easily add functions to SSI.
call_integration_hook('integrate_SSI');
+// Ignore a call to ssi_* functions if we are not using SSI.php
+if (empty($modSettings['allow_ssi_functions_anywhere']) && isset($_GET['ssi_function']) && basename($_SERVER['PHP_SELF']) !== 'SSI.php')
+ unset($_GET['ssi_function']);
// Call a function passed by GET.
if (isset($_GET['ssi_function']) && function_exists('ssi_' . $_GET['ssi_function']) && (!empty($modSettings['allow_guestAccess']) || !$user_info['is_guest']))
{
如果您熟悉 SMF,这就是您通常使用其服务器端的方式,包括:
//foo.php at http://example/foo.php
<?php
require('./SSI.php'); //assuming we're at SMF's root
//...
?>
但对于未经训练的人来说,访问 http://example/foo.php?ssi_function=something
will cause ssi_something
to be called inside SSI.php
是隐藏的,有效地绕过了 foo.php
的正常行为。
我可以在 require
之前添加这个,但我可以避免重定向:
if(isset($_GET['ssi_function']))
{
unset($_GET['ssi_function']);
return header('Location: ?' . http_build_query($_GET));
}
我已经打开了 issue on GitHub,但是我还有什么其他选择可以解决这个问题?
正如您所提到的,这是 SMF 中依赖于实现的行为。在这种情况下,您不需要进行重定向,因为 $_GET
超全局变量是可变的,只需删除 ssi_function
参数就足够了。
此错误已在 #4038 中修复。
@@ -177,6 +177,9 @@
// Have the ability to easily add functions to SSI.
call_integration_hook('integrate_SSI');
+// Ignore a call to ssi_* functions if we are not using SSI.php
+if (empty($modSettings['allow_ssi_functions_anywhere']) && isset($_GET['ssi_function']) && basename($_SERVER['PHP_SELF']) !== 'SSI.php')
+ unset($_GET['ssi_function']);
// Call a function passed by GET.
if (isset($_GET['ssi_function']) && function_exists('ssi_' . $_GET['ssi_function']) && (!empty($modSettings['allow_guestAccess']) || !$user_info['is_guest']))
{