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

Wes*_*rch 23 php security input

CodeIgniter PHP框架中,有一个函数可以自动运行每个请求,其中包括过滤GET/POST/COOKIE数组键,并在遇到它认为不安全的字符时杀死应用程序.

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

就像是:

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

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

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

goa*_*oat 18

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

$_SESSION = $_POST;
Run Code Online (Sandbox Code Playgroud)

一个鲜为人知的秘密是,$_SESSION是"特殊",不能处理管道字符,|作为一个顶级阵列的关键.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);
Run Code Online (Sandbox Code Playgroud)

我不是说这就是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>";
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • 为了参考/好奇,这个关于php.net的评论是我了解角色替换的东西:http://www.php.net/manual/en/language.variables.external.php#81080根据海报:*"PHP转换为_(下划线)的字段名称字符的完整列表如下(不仅仅是点):chr(32)()(空格)chr(46)(.)(点)chr(91)( [)(空方括号)chr(128) - chr(159)(各种).PHP不可逆地修改包含这些字符的字段名称,以保持与不推荐使用的register_globals功能的兼容性."* (2认同)
  • 作为一个兴趣点,PHP 5.4中不再出现这种情况. (2认同)

Kri*_*ian 9

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

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

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

我觉得他们过度保护只是因为CodeIgniter如此广泛使用,他们需要保护他们自己还没有想到的东西,因为他们的用户可能对这些攻击的了解程度低于CodeIgniter的开发人员.

  • 我想这可能也是"不设置"变量或其他东西,并且它们会杀死程序,因为它们*假设*它是恶意的.这个答案对我有用,似乎这个函数不是为防止任何特定类型的攻击而设计的,或者是专门针对输入键的攻击.@AlixAxel:如果你不同意,你的对位是什么? (2认同)