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

2022-08-30 18:27:25

CodeIgniter PHP 框架中,有一个函数可以自动在每个请求上运行,该函数除其他外,还会过滤 GET/POST/COOKIE 数组键,并在应用程序遇到它认为不安全的字符时将其终止。

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

像这样:

// 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


答案 1

您经常在菜鸟代码中看到此垃圾:

$_SESSION = $_POST;

一个鲜为人知的秘密是,_SESSION美元是“特殊的”,无法将管道字符作为顶级数组键来处理。php 无法在关闭/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时不是关键。

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


答案 2

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

  • 魔术报价
  • 最终可能导致SQL注入的事情
  • 可以通过 shell 命令执行的字符串
  • 可能与您的网址冲突的内容
  • 可能与 HTML 冲突的内容
  • 类似于目录遍历攻击的事物
  • 跨站点脚本 (XSS) 攻击

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

我有一种感觉,他们过度保护仅仅是因为CodeIgniter被广泛使用,以至于他们需要保护自己还没有想到的东西,以便他们的用户可能比CodeIgniter的开发人员更不了解这种攻击。


推荐