如何使用extract安全地创建PHP变量

时间:2021-10-01 23:07:07

In my previous post i ask how to create variables from an array ( PHP Variables made with foreach ) i got several answers and i was testing extract() but i have seen several against it for security reasons.

在我之前的帖子中,我问如何从数组创建变量(使用foreach制作的PHP变量)我得到了几个答案,我正在测试extract()但是出于安全原因我看过几个反对它。

Now my question here is how can i use extract in a secure way from a $_POST that has an array that was made using jquery serialized.

现在我的问题是如何以安全的方式从$ _POST中使用提取,该$ _POST具有使用jquery序列化生成的数组。

With secure i mean that if a user inputs the wrong data, the secure way can take care of that with no problems.

安全,我的意思是,如果用户输入错误的数据,安全的方式可以毫无问题地处理。

THe PHP Site has a small warning in the extract command the says the following:

PHP站点在extract命令中有一个小警告,说明如下:

Do not use extract() on untrusted data, like user input (i.e. $_GET, $_FILES, etc.). If you do, for example if you want to run old code that relies on register_globals temporarily, make sure you use one of the non-overwriting extract_type values such as EXTR_SKIP and be aware that you should extract in the same order that's defined in variables_order within the php.ini.

不要对不受信任的数据使用extract(),例如用户输入(即$ _GET,$ _FILES等)。如果您这样做,例如,如果您想要运行暂时依赖于register_globals的旧代码,请确保使用其中一个非重写的extract_type值,例如EXTR_SKIP,并注意您应该以与variables_order中定义的顺序相同的顺序提取php.ini。

It warns about the use but does not provide an example at least of how to solve the user of extract in a secure way.

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

6 个解决方案

#1


10  

The best option is to not use extract() at all. It's a bad design decision from the days when PHP was the equivalent of wet toilet paper for writing secure code.

最好的选择是根本不使用extract()。从用于编写安全代码的PHP相当于湿卫生纸的日子来看,这是一个糟糕的设计决定。

It may be painful, but it is far better to write out a long sequence of:

这可能是痛苦的,但写出一长串序列要好得多:

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

or simply use $_POST['var1'] and company everywhere in your code.

或者只是在代码中的任何地方使用$ _POST ['var1']和公司。

As soon as you start using extract, you're giving malicious users a potential way into your code, no matter how much time/effort you put into it. You don't drill a hole through a bank vault door because it's too annoying to have to open the door each time to let some money out. Once there's a hole, it will be exploited.

一旦您开始使用数据提取,您就可以为恶意用户提供进入代码的潜在方式,无论您投入多少时间/精力。你没有在银行金库门上钻一个洞,因为每次都要打开一些钱就太烦人了。一旦有洞,它就会被利用。

#2


7  

Don't use extract(), just use foreach() on POST/GET to create your own array/object. extract() will be nightmare to debug once your code starts getting bigger.

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

#3


6  

This is secure enough as long as you use a prefix that doesn't exist in other variables:

只要您使用其他变量中不存在的前缀,这就足够安全了:

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

The reason why extract might be dangerous is the same as using register_globals.

提取可能有危险的原因与使用register_globals相同。

#4


1  

There is nothing wrong with extract if you only use it for partial extraction of known input variables. It's not the nicest syntax but doable with:

如果仅将其用于部分提取已知输入变量,则提取没有任何问题。它不是最好的语法,但可以用:

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

This cuts down on the possible $_POST variables and will not extract unexpected stuff. The general benefit is that you can still apply some filter function using array_map for example. In some settings it reduces code clutter in comparison to individual variable copying.

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

#5


1  

What's about use a simple foreach instead extract():

什么是使用简单的foreach而不是extract():

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

So you can deal adding some security code on the $$k = $v; part.

所以你可以在$$ k = $ v上添加一些安全代码;部分。

#6


1  

Its dangerous to use extract in global scope and for _REQUEST, _GET, _POST, _COOKIE.

在全局范围内使用提取物以及_REQUEST,_GET,_POST,_COOKIE是危险的。

However if you allow only the variables you are going to use by use of a filtering mechanism and unset everything that comes from outside, you can use extract.

但是,如果您只允许使用过滤机制使用的变量并取消设置来自外部的所有内容,则可以使用extract。

For example, if you are directly feeding _REQUEST, _GET, _POST, _COOKIE into a function which will do the extract() inside and let out only the ones you define in return(), then you are safe too. Because whatever else is extracted - including variables from malicious attempts - will remain inside the function scope and wont be able to do anything.

例如,如果您直接将_REQUEST,_GET,_POST,_COOKIE提供给一个函数,该函数将在内部执行extract()并且只释放您在return()中定义的函数,那么您也是安全的。因为提取的任何其他东西 - 包括来自恶意企图的变量 - 将保留在功能范围内并且不能做任何事情。

So, extract() respects scope - anything you extract inside a function stays inside that function, anything you extract inside a class method stays in the scope of that class method and does not get out anywhere without you letting them.

因此,extract()尊重范围 - 您在函数内提取的任何内容都保留在该函数内部,您在类方法中提取的任何内容都保留在该类方法的范围内,并且在没有您放弃它的情况下不会离开任何地方。

Which means in global scope and in function/object scope you can safely use extract for trusted data.

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

Assuming that $args is an associative array :

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


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

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

}

Your variables will stay inside the scope of the function.

您的变量将保留在函数的范围内。

Same for a class method :

类方法相同:


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

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

     }

}

#1


10  

The best option is to not use extract() at all. It's a bad design decision from the days when PHP was the equivalent of wet toilet paper for writing secure code.

最好的选择是根本不使用extract()。从用于编写安全代码的PHP相当于湿卫生纸的日子来看,这是一个糟糕的设计决定。

It may be painful, but it is far better to write out a long sequence of:

这可能是痛苦的,但写出一长串序列要好得多:

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

or simply use $_POST['var1'] and company everywhere in your code.

或者只是在代码中的任何地方使用$ _POST ['var1']和公司。

As soon as you start using extract, you're giving malicious users a potential way into your code, no matter how much time/effort you put into it. You don't drill a hole through a bank vault door because it's too annoying to have to open the door each time to let some money out. Once there's a hole, it will be exploited.

一旦您开始使用数据提取,您就可以为恶意用户提供进入代码的潜在方式,无论您投入多少时间/精力。你没有在银行金库门上钻一个洞,因为每次都要打开一些钱就太烦人了。一旦有洞,它就会被利用。

#2


7  

Don't use extract(), just use foreach() on POST/GET to create your own array/object. extract() will be nightmare to debug once your code starts getting bigger.

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

#3


6  

This is secure enough as long as you use a prefix that doesn't exist in other variables:

只要您使用其他变量中不存在的前缀,这就足够安全了:

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

The reason why extract might be dangerous is the same as using register_globals.

提取可能有危险的原因与使用register_globals相同。

#4


1  

There is nothing wrong with extract if you only use it for partial extraction of known input variables. It's not the nicest syntax but doable with:

如果仅将其用于部分提取已知输入变量,则提取没有任何问题。它不是最好的语法,但可以用:

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

This cuts down on the possible $_POST variables and will not extract unexpected stuff. The general benefit is that you can still apply some filter function using array_map for example. In some settings it reduces code clutter in comparison to individual variable copying.

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

#5


1  

What's about use a simple foreach instead extract():

什么是使用简单的foreach而不是extract():

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

So you can deal adding some security code on the $$k = $v; part.

所以你可以在$$ k = $ v上添加一些安全代码;部分。

#6


1  

Its dangerous to use extract in global scope and for _REQUEST, _GET, _POST, _COOKIE.

在全局范围内使用提取物以及_REQUEST,_GET,_POST,_COOKIE是危险的。

However if you allow only the variables you are going to use by use of a filtering mechanism and unset everything that comes from outside, you can use extract.

但是,如果您只允许使用过滤机制使用的变量并取消设置来自外部的所有内容,则可以使用extract。

For example, if you are directly feeding _REQUEST, _GET, _POST, _COOKIE into a function which will do the extract() inside and let out only the ones you define in return(), then you are safe too. Because whatever else is extracted - including variables from malicious attempts - will remain inside the function scope and wont be able to do anything.

例如,如果您直接将_REQUEST,_GET,_POST,_COOKIE提供给一个函数,该函数将在内部执行extract()并且只释放您在return()中定义的函数,那么您也是安全的。因为提取的任何其他东西 - 包括来自恶意企图的变量 - 将保留在功能范围内并且不能做任何事情。

So, extract() respects scope - anything you extract inside a function stays inside that function, anything you extract inside a class method stays in the scope of that class method and does not get out anywhere without you letting them.

因此,extract()尊重范围 - 您在函数内提取的任何内容都保留在该函数内部,您在类方法中提取的任何内容都保留在该类方法的范围内,并且在没有您放弃它的情况下不会离开任何地方。

Which means in global scope and in function/object scope you can safely use extract for trusted data.

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

Assuming that $args is an associative array :

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


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

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

}

Your variables will stay inside the scope of the function.

您的变量将保留在函数的范围内。

Same for a class method :

类方法相同:


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

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

     }

}