PHP V5.2 中的新增功能,第 2 部分: 使用新输入过滤扩展功能

来源:百度文库 编辑:神马文学网 时间:2024/07/03 11:58:00
本文是共有五部分的系列文章的第二部分,我们将继续介绍 PHP V5.2 的新增功能,本文主要介绍输入过滤。
接受用户输入或来自不受信任来源的任何其他数据是 PHP开发人员在开发应用程序时可能承担的最常见风险之一。您经常需要引入来自未知来源的数据以使应用程序运行,但是这就给黑客提供了插入任意代码或以其他方式使用应用程序的机会。从 PHP V5.2开始,输入过滤扩展功能将被默认启用,以使您可以更轻松地针对此类操作采取措施。输入过滤扩展功能提供了一组函数来解析和检查输入,然后在函数中使用此输入。
我们将考察使用这些函数解析和检查输入而不进行手动编码的原因,并介绍一些如何使用这些新函数的基本示例。
输入是大多数应用程序的关键。我们的应用程序将接收大量信息并使用微处理器的能力来处理这些信息。我们可以控制输入进入应用程序的位置,但是我们不能控制输入此数据的用户的意图。PHP 最初被开发为一种轻松的方法,用于开发从 HTML表单收集输入的脚本。它现在的功能早已不限于此了,但是我们现在仍然在用它来收集和操作来自许多不受信任的源的数据。即使是单独的数据输入职员也可能无意识地向应用程序发送一些问题数据,甚至也必须将其视为不受信任的源。
安全是目前十分热门的问题,并且随着每次通过的硬件和软件修订而变得更加热门。我们总是说得很好听,但是由于情况很复杂,因此我们往往在系统保护的关键点 ——输入上做得差强人意。方法有很多并且实现起来很复杂。我们完成应用程序有严格的最后期限并且必须履行项目经理的最后期限。
保护自己免于恶意代码攻击的一种方法是确保接收到预期的输入。在本文中,我们将查看一个阻止用户输入不适当的 JavaScript 的示例,并向您展示如何将那些标记从输入中剥离出来,返回实际需要的内容。
PHP V5.0 以后的版本中提供了输入过滤扩展功能以使您可以更轻松地获得安全性。PHP V5.2 版本首次默认启用了此功能并实现了开箱即用。




回页首
在您的编程经历中可能听说过术语:输入验证。它是应用程序开发过程中至关重要的部分,用于确保传入数据在上下文和内容上都是正确的。程序员可以通过正则表达式和测试来查看值是否满足标准(例如,要求输入电子邮件地址并需要确保输入格式正确时)。如果需要排除 Hotmail 或 Gmail等免费电子邮件地址,也可以借助此方法。您将使用正则表达式来阻止包含 “hotmail.com” 或 “gmail.com” 的任何电子邮件地址。
通常认为这类 “处理基本检查以确保输入数据满足某种标准” 就是验证。在这种情况下,需要确保不必清理数据,或者确实可获得查找的数据。验证的目标就是要避免一些简单错误,例如尝试将 NULL 放入不接受这种值的字段。
错误的数据或恶意构造的数据导致的错误可能带来毁灭性的后果。您将需要全力实现一种更全面的过滤此信息的方法,这种方法需涵盖针对每种数据类型的所有可能测试,而不是执行千篇一律的任务或重复的任务。通常,您可能没注意到测试或编写不完整的正则表达式。过滤器扩展功能将帮助提供更完整的输入评估,同时减少重复代码编写工作。在这种情况下,过滤与验证的不同之处就在于过滤在安全性上更全面。




回页首
让我们进一步查看扩展功能的详细信息。过滤扩展功能有两种过滤器:Sanitizing 和 Logical。
Sanitizing过滤器只是允许或禁止字符串中的字符并将清理后的字符串作为结果返回。无论您将哪种数据格式传入这些函数,它们将始终返回字符串。对于特定类型的使用,这是至关重要的,因为您可以阻止用户发送不适当的输入并导致异常结果。例如,用户可以发现文本块的输入被返回到以下页面上并且要利用那些返回信息。如果清理输入,则将删除输入的所有危险部分。
Logical 过滤器将对变量执行测试并根据测试提供 true 或 false 结果。然后您可以使用结果来决定如何处理数据或获得用户的地址。这种过滤器的简单示例是验证年龄。逻辑测试还可以针对类似 Perl 的正则表达式进行测试。
让我们看看在进行过滤和验证时使用这些函数的一些方法,了解如何将过滤引入应用程序。




回页首
让我们开始使用过滤扩展功能的清理应用程序来过滤不需要的代码块。
在这个示例应用程序中,您有一张简单的表单,它接收三个问题和三个答案。表单本身没有使用验证或过滤。查看源代码时,一个不幸的用户相信这是真的,并且决定通过编写包括抛出警报的 JavaScript调用的文本块来测试表单。如果警报弹出,告诉他输入的所有内容都将真正被接受并由应用程序使用而不进行过滤,这将证明他是正确的。


What is your name?






What is your favorite color?





What is the airspeed of an unladen swallow?











清单 1 是接受用户输入的常见HTML 表单。要求用户提供一些基本信息并且简单地将其返回,而不进行任何其他操作。在图 1 中,您可以看到用户已经输入了一些信息并准备发送JavaScript 代码,如果不完成清理工作,这段 JavaScript 代码将发送警报。

接下来,创建一个脚本来捕获表单变量并在另一个页面中将其打印输出。

echo "You are " . $_GET[‘1‘] . ".
\n";
echo "Your favorite color is " . $_GET[‘2‘] . ".
\n";
echo "The airspeed of an unladen swallow is " . $_GET[‘3‘] . ".
\n";
?>

现在您可以看到如果只是返回这个输入而不使用任何类型的过滤将会发生什么情况。

如您所见,不幸的用户已经执行了一些随机代码。假定,这段代码只位于客户端(不幸用户自己的 PC 计算在内,并且在这种情况下不表示对应用程序构成威胁),但是它肯定不是有效输入。




回页首
清单 3 演示了使用 filter_var() 的 FILTER_SANITIZE_STRING 选项进行清理的简单示例。
echo "You are " . filter_var($_GET[‘1‘], FILTER_SANITIZE_STRING) . ".
\n";
echo "Your favorite color is " . filter_var($_GET[‘2‘], FILTER_SANITIZE_STRING) .
".
\n";
echo "The airspeed of an unladen swallow is " . filter_var($_GET[‘3‘], FILTER_SANITIZE_STRING)
. ".
\n";
?>
如您所见,开始使用 filter_var() 函数来清理输入并使其有效并且安全。在这种情况下,使用选项 FILTER_SANITIZE_STRING,该选项将获取输入、删除所有 HTML 标记并选择性地编码或删除特定字符。
由于它将除去 HTML 标记,因此尝试运行 JavaScript 将失败,并且从脚本中获得更适当的结果。

与尝试用正则表达式和字符串函数手动完成此工作相比,使用 filter_var() 函数将极大地减少编码量。在那种情况下,您将必须编写只执行 HTML 代码块的另外若干行代码和显式正则表达式,并且解析整个输入的文本块以确保没有遗漏任何 HTML 标记。而使用提供的函数将更简单。




回页首
一些输入是数字或有指定的式样。在这些情况下,您可以使用逻辑过滤选项并针对表达式或其他逻辑测试检查数据。如果表达式读到true,则数据将成功通过过滤器。如果逻辑测试证明数据为false,则数据将不能通过过滤器。首先,我们将设置一个简单的逻辑测试用于检查确保燕子坠落的速度在规定的范围内,因为燕子的空中速度可能不同。设置完测试后,我们将添加一些代码来告诉用户答案是否不正确。正确答案应当只需重复。
echo "You are " . $_GET[‘1‘] . ".
\n";
echo "Your favorite color is " . $_GET[‘2‘] . ".\n\n";
$minSpeed = 12;
$maxSpeed = 13;
$airspeed = filter_var($_GET[‘3‘], FILTER_VALIDATE_INT, array("options" =>
array("min_range"=>$minSpeed, "max_range"=>$maxSpeed)));
echo "The airspeed of an unladen swallow is " . $airspeed . ".\n\n";
?>
清单 4 将根据速度的最小值和最大值范围检查坠落的燕子问题的答案。这可以简单地确保它确实是一个 INT 变量,但是也在 $minSpeed 和 $maxSpeed 中添加了一个范围。如果用户答案不在可接受的值的范围内,结果将得到 FALSE。随后可以测试这个答案并且把正确答案返回给用户。在这种情况下,我们将直言不讳。
echo "You are " . $_GET[‘1‘] . ".
\n";
echo "Your favorite color is " . $_GET[‘2‘] . ".\n\n";
$minSpeed = 12;
$maxSpeed = 13;
$airspeed = filter_var($_GET[‘3‘], FILTER_VALIDATE_INT, array("options" =>
array("min_range"=>$minSpeed, "max_range"=>$maxSpeed)));
If ($airspeed === FALSE){
Echo "

WRONG!

";
}else{
echo "The airspeed of an unladen swallow is " . $airspeed . ".\n\n";
}
?>
我们已经遵从逻辑测试成功地测试了传入数据,并且向用户显示了正确结果或者一些负面的反馈。不管怎样,我们已经使用了过滤器来确保为输入提供了正确答案。




回页首
“PHP V5.2 中的新增功能”这一系列文章(共五部分)的第 2部分集中介绍了输入过滤。我们查看了以下两者的差异:简单输入验证以捕获不要求任何清理的简单错误,以及旨在捕获潜在的更具破坏性的输入错误和问题的输入过滤。然后查看了两种类型的过滤扩展功能:Sanitizing 和 Logical,并浏览了两者的示例。在第 3 部分中,我们将查看新的JSON 扩展功能,它将为 PHP 开发人员开发 Ajax 应用程序(使用 JSON 的)提供更好的支持。
学习
您可以参阅本文在 developerWorks 全球站点上的英文原文 。
阅读 “PHP V5.2 中的新增功能,第 1 部分” 了解如何跟踪内存使用量的更多信息。
阅读PHP V5.2 发行声明。
要获得关于在 PHP 中使用正则表达式的优秀文章,请参阅 “如何在 PHP 中使用正则表达式”。
获得 PHP.net过滤函数 文档。
访问PHP.net 获得 PHP 文档。
要获得过滤和验证的其他有用示例,请阅读 “Spam filtering techniques”。
要获得讨论 Register Globals 和安全问题的文章,请参阅 “审计 PHP,第 1 部分: 理解 register_globals”。
要获得关于 PHP 应用程序安全的进一步讨论,请参阅 “确保 PHP 应用程序的安全”。
“A step-by-step how-to guide to install, configure, and test a Linux, Apache, Informix, and PHP server” 包含关于如何编译适用于 Linux® 的 PHP 解释程序的部分。
在 “PHP V5 迁移指南” 中了解如何将在 PHP V4 中开发的代码迁移到 V5 中。
要获得学习使用 PHP 进行编程的教程,请查看 developerWorks 的 “学习 PHP” 系列。
Planet PHP 是 PHP 开发者社区新闻资源。
PHP.net 是 PHP 开发者的资源。
查看 “PHP 推荐读物列表”。
浏览 developerWorks 上的所有PHP 文章 和PHP 教程。
查看 IBM developerWorks 的PHP 项目资源 扩展 PHP 技巧。
收听针对软件开发人员的有趣访谈和讨论,一定要访问developerWorks podcast。
随时关注 developerWorks 的技术事件和网络广播。
查看最近将在全球举办的面向 IBM 开放源码开发人员的研讨会、交易展览、网络广播和其他活动。
访问 developerWorks开源软件技术专区,获得丰富的 how-to 信息、工具和项目更新,帮助您用开放源码技术进行开发,并与 IBM 产品结合使用。
访问Safari 在线书店 浏览开放源码技术的各种参考资料。