PHP 表单验证
本章节和下一章节介绍如何使用 PHP 验证表单数据。
PHP 表单验证
处理 PHP 表单时要考虑 **安全性**!
这些页面将展示如何处理 PHP 表单并考虑到安全性。正确验证表单数据对于保护你的表单免受黑客和垃圾邮件发送者的攻击非常重要!
我们将在这几章节中使用的 HTML 表单包含各种输入字段:必填和可选文本字段、单选按钮和提交按钮
上面表单的验证规则如下
字段 | 验证规则 |
---|---|
姓名 | 必填。+ 只能包含字母和空格 |
电子邮件 | 必填。+ 必须包含有效的电子邮件地址(包含 @ 和 .) |
网站 | 可选。如果存在,则必须包含有效的 URL |
评论 | 可选。多行输入字段(textarea) |
性别 | 必填。必须选择一个 |
首先,我们将看一下表单的纯 HTML 代码
文本字段
姓名、电子邮件和网站字段是文本输入元素,评论字段是 textarea。
HTML 代码如下
Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>
单选按钮
性别字段是单选按钮,HTML 代码如下
Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male
<input type="radio" name="gender" value="other">Other
表单元素
表单的 HTML 代码如下
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
当提交表单时,表单数据使用 method="post" 方法发送。
什么是 $_SERVER["PHP_SELF"]
变量?
The $_SERVER["PHP_SELF"]
是一个超全局变量,它返回当前执行脚本的文件名。
因此,$_SERVER["PHP_SELF"]
将提交的表单数据发送到页面本身,而不是跳转到另一个页面。这样,用户将在与表单相同的页面上获得错误消息。
什么是 htmlspecialchars()
函数?
The htmlspecialchars()
函数将特殊字符转换为 HTML 实体。这意味着它将替换 <
和 >
等 HTML 字符 <
和 >
。这可以防止攻击者通过在表单中注入 HTML 或 Javascript 代码(跨站点脚本攻击)来利用代码。
警告!
The $_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
http://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> 标签中!** 黑客可以将用户重定向到另一个服务器上的文件,而该文件可能包含恶意代码,可以更改全局变量或将表单提交到另一个地址以保存用户数据,例如。
如何避免 $_SERVER["PHP_SELF"] 漏洞?
$_SERVER["PHP_SELF"]
漏洞可以通过使用 htmlspecialchars()
函数来避免。
表单代码应该如下所示
<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('http://www.hacked.com')</script>
- 这将不会被执行,因为它将被保存为 HTML 转义代码,如下所示
<script>location.href('http://www.hacked.com')</script>
现在,此代码可以安全地显示在页面上或电子邮件中。
当用户提交表单时,我们还将执行另外两件事
- 从用户输入数据中去除不必要的字符(多余空格、制表符、换行符)(使用 PHP 的
trim()
函数) - 从用户输入数据中删除反斜杠
\
(使用 PHP 的stripslashes()
函数)
下一步是创建一个函数,它将为我们完成所有检查(这比一遍又一遍地编写相同的代码更方便)。
我们将这个函数命名为 test_input()
。
现在,我们可以使用 test_input()
函数检查每个 $_POST
变量,脚本如下所示
示例
// define variables and set to empty values
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$comment = test_input($_POST["comment"]);
$gender = test_input($_POST["gender"]);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
运行示例 »
请注意,在脚本开头,我们使用 $_SERVER["REQUEST_METHOD"]
检查表单是否已提交。如果 REQUEST_METHOD
为 POST
,则表单已提交 - 应该进行验证。如果没有提交,请跳过验证并显示一个空白表单。
但是,在上面的示例中,所有输入字段都是可选的。即使用户没有输入任何数据,脚本也能正常工作。
下一步是使输入字段成为必填项,并在需要时创建错误消息。