使用extract($ _REQUEST,EXTR_IF_EXISTS)是否安全?

时间:2013-03-21 21:28:38

标签: php security extract

在函数(不是类方法)中,如果事先定义变量,使用extract( $_REQUEST, EXTR_IF_EXISTS )是否安全?

示例:

$a = $b = $c = '';
extract( $_REQUEST, EXTR_IF_EXISTS );

或者这会允许恶意攻击者覆盖PHP全局和其他敏感内容吗?

4 个答案:

答案 0 :(得分:3)

可以这样做,但你可以轻松避免这样做:

$a = isset($_REQUEST['a']) ? $_REQUEST['a'] : '';
$b = isset($_REQUEST['b']) ? $_REQUEST['b'] : '';
$c = isset($_REQUEST['c']) ? $_REQUEST['c'] : '';

然后你可以确保没有其他东西进入你当前的范围。

如果您只是希望您的代码更漂亮,请考虑使用全局帮助函数:

function request($k, $def=''){
    return isset($_REQUEST[$k]) ? $_REQUEST[$k] : $def;
}

然后你可以根据需要进行初始化,使用unset args的默认值:

$a = request('a');
$b = request('b', null);
$c = request('c', "hello");

如果您真的想使用extract,请尝试以下操作:

function requested($a){
    return array_intersect_key($_REQUEST, array_flip($a));
}

extract( requested(array('a', 'b', 'c')), EXTR_IF_EXISTS );

首先修改$_REQUEST以仅包含所需的键,然后在其上运行提取。

答案 1 :(得分:2)

嗯,这不安全。有人可以这样做:www.example.com?_SERVER['anything']或者如果他有任何知识,他可以尝试将某些东西注入另一个变量。它仍然是某种猜谜游戏,但它是可能的。

当提取文件位于错误的位置并替换重要内容时,一个输入名称中的一个输入错误可能会弄乱您的整个程序。像这样的错误很难调试。

答案 2 :(得分:1)

我认为使用extract()有太多可疑,因为你几乎必须在本地名称空间中才能真正知道哪些变量已被定义。

我将继续沿着这些方向前进,这不是很漂亮,但仍然很容易看出哪些变量被$_REQUEST作为输入接受:

foreach ( array(
    'a',
    'b',
    'c',
    'foo' )
as $auth_var){
    if ( isset( $_REQUEST[$auth_var] ) ) ${$auth_var} = $_REQUEST[$auth_var];
}

更新

我比我更好地挖掘Cal的解决方案。它看起来也更好:

extract ( array_intersect_key( $_REQUEST, array_flip( array(
    'a',
    'b',
    'c',
    'foo' )
) ) );

答案 3 :(得分:0)

该代码符合您的期望,但如果您将其置于错误的位置,当然可能会出错:

include ('/some/file/with/super/secret/config/in.php');

$a = $b = $c = '';
extract( $_REQUEST, EXTR_IF_EXISTS );

但是,只要你知道自己在做什么以及你所处的范围,就可以了。

我个人可能不会写这个,但那取决于你想要做什么。

如果您在服务器上运行,请记住$ _SERVER可以被此覆盖。事实上,如果没有琐碎的CLI应用程序,请不要使用它,这太可怕了!