Support»Register Globals

register_globals and cross-site scripting

This page is still incomplete.

Affects version 1.2.6 to 1.2.9.2 and fixed in version 1.2.9.3.

Triple defense

Qdig now protects itself from this vulnerability in three ways.

  1. Initialize the variables.
  2. Disable the feature if register_globals is enabled.
  3. Protect global variables from register_globals.

Initialize the variables

These two lines are added in the Settings section of the script:

$pre_gallery  = '';
$post_gallery = '';

Disable the feature if register_globals is enabled

This solution disables the feature on servers where register_globals is enabled. Near the beginning of the Output section of the script, this line is changed:

if (isset($pre_gallery)) { echo $pre_gallery; }

is now

if (!ini_get('register_globals')) { echo @$pre_gallery; }

and near the end of the script, this line is changed:

if (isset($post_gallery)) { echo $post_gallery; }

is now

if (!ini_get('register_globals')) { echo @$post_gallery; }

Protect global variables from register_globals

The key portion of this solution was provided by Patrick R. Michaud, author of PmWiki.

The following code replaces some existing code in the script:

// Get global variables and protect them from register_globals.
$get_vars = ($_GET) ? $_GET : $HTTP_GET_VARS;
$post_vars = ($_POST) ? $_POST : $HTTP_POST_VARS;
$cookie_vars = ($_COOKIE) ? $_COOKIE : $HTTP_COOKIE_VARS;
$request_vars = ($_REQUEST)
    ? $_REQUEST
    : array_merge($get_vars, $post_vars, $cookie_vars);
if (ini_get('register_globals')) {
    if (!is_array($request_vars)) {
      securityExit('Security Violation'); }
    foreach($request_vars as $k=>$v) {
        if (preg_match('/^(GLOBALS|_SERVER|_GET|_POST|_COOKIE'
          .'|_FILES|_ENV|_REQUEST|_SESSION)$/i', $k))
        {
            securityExit('Security violation');
        }
        unset(${$k});
    }
}

Generic version

Here's a generic version that can be used in a script other than Qdig that's running under PHP 4.1.0 or greater:

// Protect global variables from register_globals.
if (ini_get('register_globals')) {
  if (!is_array($_REQUEST)) { exit('Security violation'); }
  foreach($_REQUEST as $k=>$v) {
    if (preg_match('/^(GLOBALS|_SERVER|_GET|_POST|_COOKIE|_FILES|_ENV|'
       .'_REQUEST|_SESSION)$/i', $k))
    {
      exit('Security violation');
    }
    unset(${$k});
  }
}