安全风险? $ _REQUEST变量...本地堆栈上的$$

时间:2010-10-21 02:48:41

标签: php security variables request globals

我之前和我的一位程序员谈过,他向我展示了他正在考虑的一段代码:

foreach($_REQUEST as $var=>$val) {
    $$var = addslashes($val);
}

他希望能够使用$varName而不必撰写$_REQUEST['varName']

我建议他使用mysql_real_escape_string代替addSlashes并且不要将$_REQUEST变量放到本地堆栈上,因为这会给黑客一个附加向量。对我来说,这似乎与旧的REGISTER_GLOBALS指令具有相同的问题。

他说没有相同的安全风险,因为这些变量都是在本地堆栈上创建的。所以我不确定,我检查了PHP变量变量页面:http://www.php.net/manual/en/language.variables.variable.php但是没有看到超级全局和安全性,而是警告框。

黑客可以轻松利用该构造吗?

5 个答案:

答案 0 :(得分:2)

我多年没有编写php,但是有没有这样做的函数?也许叫extract

关于在用户输入的数据中使用该功能有一些警告..这些警告也适用于您的代码段。

答案 1 :(得分:2)

这就像回归6年的PHP安全性增强......基本上,register_globalsmagic_quotes放在一起!这两个在最近的PHP版本中被标记为已弃用,并且将从未来的版本中删除,原因非常充分。

想象一下以下代码:

if ($is_admin) {
    do_administrative_task();
}

现在有人发出以下请求:

http://www.example.com/script.php?is_admin=1

就这样,你是管理员!

同样,addslashes()并没有真正提供任何针对SQL注入攻击的保护,因为它不了解现代字符集。制作一些可以绕过addslashes()和pwn你的数据库的东西是非常容易的。

答案 2 :(得分:1)

“本地堆栈”与它无关。它仍然允许任何人在代码的某些部分中创建一个新的变量,程序员可能没有这个变量。

如果他真的想要从$_REQUEST中取出请求参数并将其全部变为变量,那么他应该只传输 代码所在的去寻找而不是更多。

沟渠addslashes()。这不仅是逃避传入数据的错误位置,也是错误的功能。

答案 3 :(得分:0)

是。如果请求URL包含...&GLOBALS[var]=1,则它将覆盖相应的全局变量。

他至少应该考虑遵循构造的安全性:

 extract($_REQUEST, EXTR_PREFIX_ALL, "var_");  // or EXTR_SKIP

这将为本地化变量提供至少一个前缀并防止覆盖全局变量。为了更好的衡量,还可以使用array_map("addslashes", $_REQUEST)或更合适的转义函数。但实际上,这只是另一个名字的magic_quotes。 (Offtopic:尝试放开mysql_query并使用PDO和预处理语句,这样更简单,更安全。)

答案 4 :(得分:0)

是的! 作为程序员,这里实际上有三个不同的问题。

  1. $_REQUEST并不比$_GET$_POST更不安全,因为默认情况下,PHP $_COOKIES优先于$_GET$_POST
  2. 设置超全局值比函数中的局部变量或对象方法局部变量更安全。
  3. 函数中最终用户创建的变量可全局访问。
  4. 让我们从顶部开始。

    1. $_POST$_GET并不比$_REQUEST更安全。从表单收到的所有信息都很脏。期。而不管。如果我可以发送伪造的cookie,我知道如何伪造POST变量。这个论点没有实际意义。
    2. 因此我们使用$var.创建一个局部变量。此变量的范围仅在函数/方法中。将超全局的内容设置为用户提供的数据的值比在清除函数/方法堆栈时擦除的局部变量更安全吗?我想知道......
    3. 让我们拿一个片段
    4. function some_function() {
         foreach($_POST as $var=>$val) {
              $$var = $val; 
        }
      }
      

      现在,如果$_POST包含名为_POST的变量,则此代码将设置包含该值的局部变量$_POST。但是,superglobals会覆盖此,并且对$_POST的任何引用都将引用超全局,而不是局部变量,因此本地$_POST是不可接受的。鉴于PHP的这种功能,不使用global关键字通常不可能完全覆盖超全局