输入密钥如何被恶意用户利用?

时间:2012-05-11 22:44:17

标签: php security input

CodeIgniter PHP框架中,有一个函数可以自动运行每个请求,其中包括filters the GET/POST/COOKIE array keys,并且如果遇到它认为不安全的字符,就会杀死该应用程序。

  

为防止恶意用户尝试利用密钥,我们会确保密钥仅以字母数字文本和其他一些项目命名。

类似的东西:

// foreach GET/POST/COOKIE keys as $str...
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
    exit('Disallowed Key Characters.');
}

例如,如果您不小心发布了<input name="TE$T">之类的内容或者有?name|first=1之类的查询字符串,则会触发此操作。

我可以看到这是在开发应用程序时强制执行常识键名称或捕获错误的好方法,但我不明白:恶意用户如何可能在$_POST数据中“利用密钥”例如?特别是因为(我会假设)输入同样可以利用,这实际上阻止了什么?

5 个答案:

答案 0 :(得分:18)

你经常在noob代码中看到这个垃圾:

$_SESSION = $_POST;

一个鲜为人知的秘密是$_SESSION is "special" and can't handle the pipe character|,作为顶级数组键。 php无法在shutdown / session_write_close期间保存会话变量,而是擦除整个数组。

session_start();

if (!isset($_SESSION['cnt'])) {
    $_SESSION['cnt'] = 0;
}

$_SESSION['cnt']++;

/* prior to php 5.4, it will never increment, because it never successfuly saves
unless you comment line below
*/
$_SESSION['a|b'] = 1;

print_r($_SESSION);

我不是说这就是CodeIgniter擦除密钥的原因,但它是众多“输入密钥可被利用的方式”之一。

也许更可能的原因是因为人们当然会做这样的事情:

if ($formPostDidntValidate) {
    echo "Please fix the form submission errors and try again\n";
    foreach ($_POST as $key => $value) {
        echo "<p>$key<br>
              <input name='$key' value='$value'></p>";
    }
}

输出请求变量而不进行适当的特定于上下文的转义,例如转义为html上下文,html属性上下文,甚至是sql上下文:

$sql = "select * from myTable where 1=1";
foreach ($_POST as $key => $value) {
    $sql .= " and $key = '$value'";
}

我已经看到很多人逃避了这个价值,但是在构建sql和/或html时没有关键。

如果你没有逃避一切,你很容易被黑客入侵。清除值不如逃避,但它比没有好,并且考虑到有多少开发人员还不够精通以了解何时以及如何逃避,我可以看到添加自动请求变量清理的吸引力。

答案 1 :(得分:9)

你的问题本身就提出了一个很好的观点:目前还不清楚究竟是什么正在受到保护。但是它可以解决一些受欢迎的项目:

  • 魔术引语
  • 最终会导致SQL injection
  • 的事情
  • 可以通过shell命令执行的字符串
  • 可能与您的网址冲突的内容
  • 可能与HTML冲突的事情
  • 类似于目录遍历攻击的内容
  • cross site scripting(XSS)攻击

但除此之外,我真的想不出为什么你总是想要通过preg_match("/^[a-z0-9:_\/-]+$/i", $str)来保护。

我觉得他们过度保护只是因为CodeIgniter被如此广泛地使用,以至于他们需要为了用户而保护他们自己还没有想到的东西。可能比CodeIgniter的开发人员更不了解此类攻击。

答案 2 :(得分:4)

在控制台中说我将表单的字段名称从name="email"更改为name="email\"); DROP TABLE users;

它不太可能是一次成功的XSS攻击,但是我可以看到类似于编码不良的PHP的损坏。 CI可能只是试图覆盖他们所有的基础,因此他们可以声称受到XSS保护。

答案 3 :(得分:3)

这种检查是浪费时间。你只能访问你期望的密钥 - 如果由于某种原因你遍历所有元素,你很可能会正确地逃避它们,无论你打算用它们做什么。

然而,看一下普通新手PHP程序员的技能(即使这个物种的成员很可能根本不使用框架),这是有道理的,你永远不会知道他将要做什么令人讨厌的事情这些代码甚至可能在没有这种检查的情况下杀死他的猫。

同样适用于拒绝包含例如“删除”作为反SQL注入措施。它很容易导致误报,如果你是使用参数化查询无论如何都是安全的。

答案 4 :(得分:2)

也许是在试图阻止this attack

攻击的工作原理是利用PHP如何构建其散列结构,以便在$_POST中生成需要任意长时间处理的密钥。

我怀疑它可能只是试图阻止更普通的SQL注入攻击。