在函数(不是类方法)中,如果事先定义变量,使用extract( $_REQUEST, EXTR_IF_EXISTS )
是否安全?
示例:
$a = $b = $c = '';
extract( $_REQUEST, EXTR_IF_EXISTS );
或者这会允许恶意攻击者覆盖PHP全局和其他敏感内容吗?
答案 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应用程序,请不要使用它,这太可怕了!