From 9ec71beedf1331fb6f49a31e7548d79567272e30 Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Sat, 26 Nov 2005 06:08:07 +0000 Subject: [PATCH] allow scripts to bypass importing vars --- ChangeLog | 3 + libraries/grab_globals.lib.php | 248 ++++++++++++++++++--------------- 2 files changed, 142 insertions(+), 109 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38a82d2e4..4d155e096 100755 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ phpMyAdmin - Changelog $Id$ $Source$ +2005-11-24 Sebastian Mendel + * libraries/grab_globals.lib.php: allow scripts to bypass importing vars + 2005-11-25 Marc Delisle * main.php: move server choice into MySQL container * libraries/select_server.lib.php: show currently selected server diff --git a/libraries/grab_globals.lib.php b/libraries/grab_globals.lib.php index ee148cdfc..f5fa35c40 100644 --- a/libraries/grab_globals.lib.php +++ b/libraries/grab_globals.lib.php @@ -12,7 +12,10 @@ * loic1 - 2001/25/11: use the new globals arrays defined with php 4.1+ */ -// just to be sure there was no import (registering) before here +/** + * just to be sure there was no import (registering) before here + * we empty the global space + */ $variables_whitelist = array ( 'GLOBALS', '_SERVER', @@ -22,6 +25,7 @@ $variables_whitelist = array ( '_FILES', '_ENV', '_COOKIE', + '_SESSION', ); foreach ( get_defined_vars() as $key => $value ) { @@ -31,82 +35,25 @@ foreach ( get_defined_vars() as $key => $value ) { } unset( $key, $value ); -// protect against older PHP versions' bug about GLOBALS overwrite -// (no need to translate this one :) ) -// but what if script.php?GLOABLS[admin]=1&GLOBALS[_REQUEST]=1 ??? + +/** + * protect against older PHP versions' bug about GLOBALS overwrite + * (no need to translate this one :) ) + * but what if script.php?GLOBALS[admin]=1&GLOBALS[_REQUEST]=1 ??? + */ if ( isset( $_REQUEST['GLOBALS'] ) || isset( $_FILES['GLOBALS'] ) || isset( $_SERVER['GLOBALS'] ) || isset( $_COOKIE['GLOBALS'] ) || isset( $_ENV['GLOBALS'] ) ) { die( 'GLOBALS overwrite attempt' ); } + require_once './libraries/session.inc.php'; -/** - * @var array $import_blacklist variable names that should NEVER be imported - * from superglobals - */ -$import_blacklist = array( - '/^cfg$/i', // PMA configuration - '/^GLOBALS$/i', // the global scope - '/^str.*$/i', // PMA strings - '/^_.*$/i', // PMA does not use variables starting with _ from extern - '/^.*\s+.*$/i', // no whitespaces anywhere - '/^[0-9]+.*$/i', // numeric variable names - //'/^PMA_.*$/i', // other PMA variables -); /** - * copy values from one array to another, usally from a superglobal into $GLOBALS - * - * @uses $GLOBALS['import_blacklist'] - * @uses preg_replace() - * @uses array_keys() - * @uses array_unique() - * @uses get_magic_quotes_gpc() to check wether stripslashes or not - * @uses stripslashes() - * @param array $array values from - * @param array $target values to - * @param boolean $sanitize prevent importing key names in $import_blacklist + * check if a subform is submitted */ -function PMA_gpc_extract($array, &$target, $sanitize = TRUE) { - if (!is_array($array)) { - return FALSE; - } - - if ( $sanitize ) { - $valid_variables = preg_replace( $GLOBALS['import_blacklist'], '', - array_keys( $array ) ); - $valid_variables = array_unique( $valid_variables ); - } else { - $valid_variables = array_keys( $array ); - } - - $is_magic_quotes = get_magic_quotes_gpc(); - - foreach ( $valid_variables as $key ) { - - if ( strlen( $key ) === 0 ) { - continue; - } - - if ( is_array( $array[$key] ) ) { - // there could be a variable coming from a cookie of - // another application, with the same name as this array - unset($target[$key]); - - PMA_gpc_extract($array[$key], $target[$key], FALSE); - } elseif ($is_magic_quotes) { - $target[$key] = stripslashes($array[$key]); - } else { - $target[$key] = $array[$key]; - } - } - return TRUE; -} - - -// check if a subform is submitted $__redirect = NULL; if ( isset( $_POST['usesubform'] ) ) { // if a subform is present and should be used @@ -123,50 +70,133 @@ if ( isset( $_POST['usesubform'] ) ) { } // end if ( isset( $_POST['usesubform'] ) ) // end check if a subform is submitted -if (!empty($_GET)) { - PMA_gpc_extract($_GET, $GLOBALS); -} // end if - -if (!empty($_POST)) { - PMA_gpc_extract($_POST, $GLOBALS); -} // end if (!empty($_POST)) - -if (!empty($_FILES)) { - foreach ($_FILES AS $name => $value) { - $$name = $value['tmp_name']; - ${$name . '_name'} = $value['name']; - } -} // end if -unset( $name, $value ); - -if (!empty($_SERVER)) { - $server_vars = array('PHP_SELF', 'HTTP_ACCEPT_LANGUAGE', 'HTTP_AUTHORIZATION'); - foreach ( $server_vars as $current ) { - // its not important HOW we detect html tags - // its more important to prevent XSS - // so its not important if we result in an invalid string, - // its even better than a XSS capable string - if ( isset( $_SERVER[$current] ) && false === strpos( $_SERVER[$current], '<' ) ) { - $$current = $_SERVER[$current]; - // already importet by register_globals? - } elseif ( ! isset( $$current ) || false !== strpos( $$current, '<' ) ) { - $$current = ''; +if ( $__redirect || ! defined( 'PMA_NO_VARIABLES_IMPORT' ) ) { + /** + * copy values from one array to another, usally from a superglobal into $GLOBALS + * + * @uses $GLOBALS['import_blacklist'] + * @uses preg_replace() + * @uses array_keys() + * @uses array_unique() + * @uses get_magic_quotes_gpc() to check wether stripslashes or not + * @uses stripslashes() + * @param array $array values from + * @param array $target values to + * @param boolean $sanitize prevent importing key names in $import_blacklist + */ + function PMA_gpc_extract($array, &$target, $sanitize = TRUE) { + if (!is_array($array)) { + return FALSE; } + + if ( $sanitize ) { + $valid_variables = preg_replace( $GLOBALS['import_blacklist'], '', + array_keys( $array ) ); + $valid_variables = array_unique( $valid_variables ); + } else { + $valid_variables = array_keys( $array ); + } + + $is_magic_quotes = get_magic_quotes_gpc(); + + foreach ( $valid_variables as $key ) { + + if ( strlen( $key ) === 0 ) { + continue; + } + + if ( is_array( $array[$key] ) ) { + // there could be a variable coming from a cookie of + // another application, with the same name as this array + unset($target[$key]); + + PMA_gpc_extract($array[$key], $target[$key], FALSE); + } elseif ($is_magic_quotes) { + $target[$key] = stripslashes($array[$key]); + } else { + $target[$key] = $array[$key]; + } + } + return TRUE; } - unset( $server_vars, $current ); -} // end if + + + /** + * @var array $import_blacklist variable names that should NEVER be imported + * from superglobals + */ + $import_blacklist = array( + '/^cfg$/i', // PMA configuration + '/^GLOBALS$/i', // the global scope + '/^str.*$/i', // PMA strings + '/^_.*$/i', // PMA does not use variables starting with _ from extern + '/^.*\s+.*$/i', // no whitespaces anywhere + '/^[0-9]+.*$/i', // numeric variable names + //'/^PMA_.*$/i', // other PMA variables + ); + + if (!empty($_GET)) { + PMA_gpc_extract($_GET, $GLOBALS); + } // end if + + if (!empty($_POST)) { + PMA_gpc_extract($_POST, $GLOBALS); + } // end if (!empty($_POST)) + + if (!empty($_FILES)) { + foreach ($_FILES AS $name => $value) { + $$name = $value['tmp_name']; + ${$name . '_name'} = $value['name']; + } + unset( $name, $value ); + } // end if + + if (!empty($_SERVER)) { + $server_vars = array('PHP_SELF', 'HTTP_ACCEPT_LANGUAGE', 'HTTP_AUTHORIZATION'); + foreach ( $server_vars as $current ) { + // its not important HOW we detect html tags + // its more important to prevent XSS + // so its not important if we result in an invalid string, + // its even better than a XSS capable string + if ( isset( $_SERVER[$current] ) && false === strpos( $_SERVER[$current], '<' ) ) { + $$current = $_SERVER[$current]; + // already importet by register_globals? + } elseif ( ! isset( $$current ) || false !== strpos( $$current, '<' ) ) { + $$current = ''; + } + } + unset( $server_vars, $current ); + } // end if + + // Security fix: disallow accessing serious server files via "?goto=" + if (isset($goto) && strpos(' ' . $goto, '/') > 0 && substr($goto, 0, 2) != './') { + unset($goto); + } // end if + + unset( $import_blacklist ); + + if ( ! empty( $__redirect ) ) { + // TODO: ensure that PMA_securePath() is defined and available + // for this script. Meanwhile we duplicate what this function does: + require('./' . preg_replace('@\.\.*@','.',$__redirect)); + exit(); + } // end if ( ! empty( $__redirect ) ) -// Security fix: disallow accessing serious server files via "?goto=" -if (isset($goto) && strpos(' ' . $goto, '/') > 0 && substr($goto, 0, 2) != './') { - unset($goto); -} // end if - -unset( $import_blacklist ); - -if ( ! empty( $__redirect ) ) { - // TODO: ensure that PMA_securePath() is defined and available - // for this script. Meanwhile we duplicate what this function does: - require('./' . preg_replace('@\.\.*@','.',$__redirect)); - exit(); -} // end if ( ! empty( $__redirect ) ) +} else { + + echo $goto . "-
\n"; + echo $_REQUEST['goto'] . "-
\n"; + echo $_GET['goto'] . "-
\n"; + echo $_POST['goto'] . "-
\n"; + + // Security fix: disallow accessing serious server files via "?goto=" + if ( isset( $_REQUEST['goto'] ) + && strpos( $_REQUEST['goto'], '\\' ) !== false + && strpos( $_REQUEST['goto'], '/' ) !== false ) { + unset( $_REQUEST['goto'], $_GET['goto'], $_POST['goto'] ); + } // end if + echo $_REQUEST['goto'] . "-
\n"; + echo $_GET['goto'] . "-
\n"; + echo $_POST['goto'] . "-
\n"; +} ?>