2

我之前和我的一位程序员交谈过,他给我看了一段他正在考虑的代码:

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

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

我建议他使用mysql_real_escape_stringaddSlashes不是将$_REQUEST变量放入本地堆栈,因为这给了黑客一个附加向量。对我来说,这似乎与旧REGISTER_GLOBALS指令有同样的问题。

他说不存在相同的安全风险,因为这些变量都是在本地堆栈上创建的。所以我不确定,我在以下位置查看了 PHP 变量变量页面:http ://www.php.net/manual/en/language.variables.variable.php但除了警告框之外没有看到对 Super Globals 和安全性的引用.

黑客可以轻松利用这种结构吗?

4

5 回答 5

2

我已经好几年没有编写 php 代码了,但是没有一个函数可以做到这一点吗?也许称为提取物

有一些关于将该函数与用户输入的数据一起使用的警告。这些警告也适用于您的代码片段。

于 2010-10-21T02:53:39.347 回答
2

这就像倒退 6 年的 PHP 安全增强功能......基本上,register_globals放在magic_quotes一起!这两个在最近的 PHP 版本中被标记为已弃用,并且出于很好的理由将从未来的版本中删除。

想象一下下面的代码:

if ($is_admin) {
    do_administrative_task();
}

现在有人提出以下要求:

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

就这样,你是管理员!

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

于 2010-10-21T03:05:00.743 回答
1

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

如果他真的想取出请求参数$_REQUEST并将它们全部变成变量,那么他应该传输代码要查找的那些,而不是更多。

和沟addslashes()。这不仅是转义传入数据的错误位置,而且也是错误的功能。

于 2010-10-21T02:55:54.637 回答
0

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

为了安全起见,他至少应该考虑以下构造:

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

这将为本地化变量提供至少一个前缀并防止覆盖全局变量。为了更好地衡量,还可以使用array_map("addslashes", $_REQUEST) 或更合适的转义功能。但实际上,这只是另一个名字的magic_quotes。(题外话:尽量放开mysql_query,使用PDO和prepared statements,更简单,更安全。)

于 2010-10-21T02:55:02.560 回答
0

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

  1. $_REQUEST并不比默认情况下 PHP优先于$_GET和更不安全。$_POST$_COOKIES$_GET$_POST
  2. 设置超全局的值比函数中的局部变量或对象方法局部变量更安全。
  3. 最终用户在函数中创建的变量是全局可访问的。

让我们从顶部开始。

  1. $_POST并且$_GET不比 更安全$_REQUEST。从表单收到的所有信息都是脏的。时期。不管。如果我可以发送伪造的 cookie,我就会知道如何伪造POST变量。争论是没有意义的。
  2. 所以我们取一个我们创建的局部变量$var.,这个变量的作用域只在函数/方法内。将超全局的内容设置为用户提供的数据的值是否比清理函数/方法堆栈时被清理的局部变量更安全?我想知道...
  3. 让我们看一个片段

 

function some_function() {
   foreach($_POST as $var=>$val) {
        $$var = $val; 
  }
}

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

于 2010-10-22T02:55:51.153 回答