Prevent "ssi_function=something" from bypassing normal control flow

61 views Asked by At

If you're familiar with SMF, this is how you normally use its server side include:

//foo.php at http://example/foo.php
<?php
require('./SSI.php'); //assuming we're at SMF's root

//...
?>

But it's hidden to the untrained eye that accessing http://example/foo.php?ssi_function=something will cause ssi_something to be called inside SSI.php, effectively bypassing the foo.php's normal behaviour.

I could prepend this before require, but I could avoid a redirection:

if(isset($_GET['ssi_function']))
{
    unset($_GET['ssi_function']);
    return header('Location: ?' . http_build_query($_GET));
}

I have already opened an issue on GitHub, but what other options do I have to counter this nuisance?

2

There are 2 answers

0
bit2shift On BEST ANSWER

This bug has been fixed in #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']))
 {
4
Carey On

As you mentioned, this is an implementation dependent behavior within SMF. You don't need to do a redirection in this case, as the $_GET superglobal is mutable, simply removing the ssi_function parameter should be enough.