2011-05-16 50 views
12

PHP变量在我以前的帖子请问如何从一个数组(PHP Variables made with foreach)我有几个答案创建变量和我测试提取物(),但我已经看到了反对一些出于安全原因。如何安全地创建与提取

现在,这里我的问题是如何使用提取的安全的方式从$ _ POST拥有这是使用jQuery做连载的阵列。

随着安全我的意思是,如果用户输入了错误的数据,羊城通可以照顾与没有问题。

PHP的网站在提取命令一个小警告说以下内容:

不要在不可信 数据提取物(),比如用户输入(即$ _ GET, $ _FILES等)。如果你这样做,例如,如果你想运行旧代码 依赖于register_globals的 暂时 ,请确保您使用非覆盖extract_type参数 值,如EXTR_SKIP的 一个,并意识到 ,你应该在相同的提取 在php.ini中定义了 variables_order。

它警告使用,但至少不提供如何以安全方式解决提取用户的示例。

+1

出了什么问题简单地使用$ _ POST [ '关键']或$ _GET [ '关键']? – Cfreak 2011-05-16 21:44:16

+0

除了近200个变量之外没有任何区别。但既然Marc B的回答我认为我必须输入每一个。 – 2011-05-16 21:46:37

+2

只是为了跟进Marc B的评论。大量变量是使用完整变量名称的一个很好的理由。您可以立即在代码中的任何地方看到它,并知道将它作为不安全的数据处理。 – Cfreak 2011-05-16 22:00:50

回答

10

最好的办法是不使用extract()可言。从PHP编写安全代码相当于湿厕纸的日子来看,这是一个糟糕的设计决定。

这可能是痛苦的,但它远不如写出来的长序列:

$var1 = $_POST['var1']; 
$var2 = $_POST['var2']; 
etc... 

或只是在代码中使用$_POST['var1']和公司无处不在。

一旦你开始使用提取物,你给恶意用户的潜在方法到你的代码,无论你有多少时间/精力投入到它。你不要在银行金库门上钻一个洞,因为每次开门都让人有钱就太烦人了。一旦出现漏洞,就会被利用。

extract($_POST, EXTR_PREFIX_ALL, 'unique_prefix'); 

为什么提取物可能是危险的原因是一样的使用register_globals

+2

谢谢你的历史。不知道。 – 2011-05-16 21:45:04

7

不要使用extract(),只需在POST/GET上使用foreach()来创建自己的数组/对象。当你的代码开始变大时,extract()将会成为噩梦来进行调试。

+0

Foreach?只要'$ myVar = $ _POST;'如果你不喜欢标准的$ _POST数组。如果您从阵列中获得了一个维度,则与解压缩一样具有相同的漏洞问题。 – 2014-01-03 08:55:02

6

这只要您使用前缀并不在其他变量存在足够安全。

+0

所以提取是安全的使用*如果你使用一个独特的前缀? – TheCrazyProfessor 2017-03-29 09:48:57

1

没有什么错extract如果你只使用它的已知输入变量的部分提取。这不是最好的语法,但可用:

extract(array_intersect_key($_POST, 
     array_flip(array("var1", "var2", "var3", "var4")))); 

这减少了可能的$ _POST变量,不会提取意外的东西。一般的好处是,您仍然可以使用array_map来应用一些过滤功能。在某些设置中,与单个变量复制相比,它减少了代码混乱。

1

什么是关于使用一个简单的foreach,而不是提取物():

foreach($_POST as $k => $v) $$k = $v; 

所以,你可以处理在$$k = $v;部分增加了一些安全代码。

+0

相同的安全问题,因为任何人都可以在浏览器中操作内嵌的数组中的数组的键和值。 – 2014-01-03 08:56:01

1

在全球范围内使用提取物和_REQUEST,_GET,_POST,_COOKIE危险。

但是,如果仅允许使用过滤机制使用的变量并取消设置来自外部的所有变量,则可以使用提取。例如,如果您直接将_REQUEST,_GET,_POST,_COOKIE放入一个函数中,该函数将执行extract()内部并仅放出您在return()中定义的函数,那么您也很安全。因为任何其他提取 - 包括来自恶意尝试的变量 - 都将保留在函数范围内,并且无法执行任何操作。因此,extract()尊重范围 - 在函数内部提取的任何东西都会保留在该函数内,因此,在类方法内部提取的任何内容都将保留在该类方法的范围内,并且不会在任何地方让出它们。

这意味着在全局范围和功能/对象范围内,您可以安全地使用提取信任数据。

假设的$ args是一个关联数组:


function funny($args) 
{ 
    extract($args); 

    // Hereon you can use the variables normally and they will stay in function scope 

} 

您的变量将保持功能的范围内。

同为一类方法:


class berserker 
{ 
    public function funny($args) 
    { 
     extract($args); 

     // Hereon you can use the variables normally and they will stay in method scope 

    } 

} 
相关问题