PHP 表单验证
本章和下一章将展示如何使用 PHP 验证表单数据。
PHP 表单验证
处理 PHP 表单时请考虑安全性!
这些页面将展示如何在考虑安全性的情况下处理 PHP 表单。正确验证表单数据对于保护您的表单免受黑客和垃圾邮件发送者的攻击非常重要!
我们将在这些章节中使用的 HTML 表单包含各种输入字段:必填和可选文本字段、单选按钮和提交按钮:
上述表单的验证规则如下:
场地 | 验证规则 |
---|---|
姓名 | 必填。+ 只能包含字母和空格 |
电子邮件 | 必填。+ 必须包含有效的电子邮件地址(带有 @ 和 .) |
网站 | 可选。如果存在,则必须包含有效的 URL |
评论 | 可选。多行输入字段(textarea) |
性别 | 必填。必须选择一个 |
首先我们来看一下表单的纯 HTML 代码:
文本字段
名称、电子邮件和网站字段是文本输入元素,评论字段是文本区域。HTML 代码如下所示:
姓名:<input type="text" name="name">
电子邮件:<input type="text" name="email">
网站:<input type="text" name="website">
评论:<textarea name="comment" rows="5" cols="40"></textarea>
单选按钮
性别字段是单选按钮,HTML 代码如下所示:
性别:
<input type="radio" name="gender" value="female">女性
<input type="radio" name="gender" value="male">男性
<input type="radio" name="gender" value="other">其他
表单元素
表单的 HTML 代码如下所示:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?> “>
当表单提交时,表单数据通过method="post"发送。
$_SERVER["PHP_SELF"] 变量是什么?
$_SERVER["PHP_SELF"] 是一个超级全局变量,它返回当前正在执行的脚本的文件名。
因此,$_SERVER["PHP_SELF"] 将提交的表单数据发送到页面本身,而不是跳转到其他页面。这样,用户将在与表单相同的页面上收到错误消息。
htmlspecialchars() 函数是什么?
htmlspecialchars() 函数将特殊字符转换为 HTML 实体。这意味着它将用 < 和 > 替换 HTML 字符(如 < 和 >)。这可以防止攻击者通过在表单中注入 HTML 或 Javascript 代码(跨站点脚本攻击)来利用代码。
PHP 表单安全性的重要说明
$_SERVER["PHP_SELF"] 变量可被黑客利用!
如果您的页面使用了 PHP_SELF,那么用户可以输入斜线 (/),然后执行一些跨站点脚本 (XSS) 命令。
跨站点脚本 (XSS) 是一种常见于 Web 应用程序中的计算机安全漏洞。XSS 使攻击者能够将客户端脚本注入其他用户查看的网页中。
假设我们在名为“test_form.php”的页面中有以下表单:
<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?> “>
现在,如果用户在地址栏中输入正常 URL,如“http://www.example.com/test_form.php”,则上述代码将被转换为:
<form method="post" action="test_form.php">
到目前为止,一切都很好。
但是,假设用户在地址栏中输入以下 URL:
https://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
在这种情况下,上述代码将被翻译为:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>
此代码添加了一个脚本标记和一个警报命令。当页面加载时,JavaScript 代码将被执行(用户将看到一个警报框)。这只是一个简单且无害的示例,展示了如何利用 PHP_SELF 变量。
请注意 任何 JavaScript 代码都可以添加到<script> tag! 例如,黑客可以将用户重定向到另一台服务器上的文件,而该文件可能包含恶意代码,可以改变全局变量或将表单提交到另一个地址以保存用户数据。
如何避免 $_SERVER["PHP_SELF"] 漏洞?
可以使用 htmlspecialchars() 函数来避免 $_SERVER["PHP_SELF"] 漏洞。
表单代码应如下所示:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?> “>
htmlspecialchars() 函数将特殊字符转换为 HTML 实体。现在,如果用户尝试利用 PHP_SELF 变量,将产生以下输出:
<form method="post" action="test_form.php/"><script>alert('hacked')</script>">
漏洞尝试失败,并且没有造成任何损害!
使用 PHP 验证表单数据
我们要做的第一件事是通过 PHP 的 htmlspecialchars() 函数传递所有变量。
当我们使用 htmlspecialchars() 函数时;如果用户尝试在文本字段中提交以下内容:
<script>location.href('https://www.hacked.com')</script>
- 这不会被执行,因为它会被保存为 HTML 转义代码,如下所示:
<script>location.href('https://www.hacked.com')</script>
该代码现在可以安全地显示在页面或电子邮件中。
当用户提交表单时我们还会做两件事:
- 从用户输入数据中删除不必要的字符(多余的空格、制表符、换行符)(使用 PHP trim() 函数)
- 从用户输入数据中删除反斜杠 (\)(使用 PHP stripslashes() 函数)
下一步是创建一个函数来为我们完成所有检查(这比一遍又一遍地编写相同的代码方便得多)。
我们将该函数命名为 test_input()。
现在,我们可以用 test_input() 函数检查每个 $_POST 变量,脚本如下所示:
例子
<?php
// 定义变量并设置为空值
$name = $email = $gender = $comment = $website = "";
如果 ($_SERVER["REQUEST_METHOD"] == "POST") {
$名称 = 测试输入($_POST["名称"]);
$email = 测试输入($_POST["email"]);
$website = 测试输入($_POST["website"]);
$评论 = test_input($_POST["评论"]);
$性别 = 测试输入($_POST["性别"]);
}
函数 test_input($data) {
$数据 = 修剪($数据);
$数据 = 剥离斜线 ($数据);
$数据 = htmlspecialchars($数据);
返回$数据;
}
?>
运行示例 »
请注意,在脚本的开头,我们使用 $_SERVER["REQUEST_METHOD"] 检查表单是否已提交。如果 REQUEST_METHOD 为 POST,则表单已提交 - 并且应该进行验证。如果尚未提交,则跳过验证并显示空白表单。
但是,在上面的例子中,所有输入字段都是可选的。即使用户不输入任何数据,脚本也能正常工作。
下一步是使输入字段成为必填字段,并在需要时创建错误消息。