3

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

例子:

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

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

4

4 回答 4

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;
}

然后您可以根据需要使用未设置参数的默认值进行初始化:

$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首先修改以仅包含您想要的键,然后在其上运行提取来工作。

于 2013-03-21T21:37:33.267 回答
2

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

此外,当提取物放在错误的位置并替换重要的东西时,一个输入名称中的一个拼写错误可能会弄乱你的整个程序。像这样的错误很难调试。

于 2013-03-21T21:30:59.920 回答
1

我认为 using 有太多的疑问,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' )
) ) );
于 2013-03-21T21:54:31.163 回答
0

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

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

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

但是,只要你知道你在哪里做,你在什么范围内,那就没问题了。

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

如果您在服务器上运行,请记住 $_SERVER 可以被它覆盖。其实少了些琐碎的CLI应用,别用这个,太吓人了!

于 2013-03-21T21:34:19.617 回答