PHP表单验证及安全

Posted Hardworking666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP表单验证及安全相关的知识,希望对你有一定的参考价值。

一、表单简介

表单(Form)在网页中主要负责数据采集功能。

一个表单有三个基本组成部分:

表单标签:这里面包含了处理表单数据所用CGI(公共网关接口)程序的URL以及数据提交到服务器的方法。

表单:包含了文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等。

表单按钮:包括提交按钮、复位按钮和一般按钮;用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作。

二、表单验证实例

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>表单验证实例(信息收集)</title>
    <style>
    .error color: #FF0000;
    </style>
</head>
<body>

<?php
// 定义变量并默认设置为空值
$nameErr = $emailErr = $genderErr = $websiteErr = "";
$name = $email = $gender = $comment = $website = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") // 检测表单是否被提交,如未提交将跳过验证并显示空白

    if (empty($_POST["name"])) // 使用empty()函数检测如为空,将显示对应的错误信息
    
        $nameErr = "名字是必需的";
    
    else
    
        $name = test_input($_POST["name"]);
        // 检测名字是否只包含大小写字母跟空格,preg_match进行正则表达式匹配
        if (!preg_match("/^[a-zA-Z ]*$/",$name))
        
            $nameErr = "只允许大小写字母和空格";
        
    

    if (empty($_POST["email"]))
    
        $emailErr = "邮箱是必需的";
    
    else
    
        $email = test_input($_POST["email"]);
        // 检测邮箱是否合法(包含'@'和'.')
        if (!preg_match("/([\\w\\-]+\\@[\\w\\-]+\\.[\\w\\-]+)/",$email))
        
            $emailErr = "非法邮箱格式";
        
    

    if (empty($_POST["website"]))
    
        $website = "";
    
    else
    
        $website = test_input($_POST["website"]);
        // 检测 URL 地址是否合法
        if (!preg_match("/\\b(?:(?:https?|ftp):\\/\\/|www\\.)[-a-z0-9+&@#\\/%?=~_|!:,.;]*[-a-z0-9+&@#\\/%=~_|]/i",$website))
        
            $websiteErr = "非法URL地址";
        
    

    if (empty($_POST["comment"]))
    
        $comment = "";
    
    else
    
        $comment = test_input($_POST["comment"]);
    

    if (empty($_POST["gender"]))
    
        $genderErr = "性别是必需的";
    
    else
    
        $gender = test_input($_POST["gender"]);
    


function test_input($data) // 将过滤函数写在自定义函数test_input()中,以提高代码的复用性

    $data = trim($data); // 去除输入数据中不必要的字符(如:空格,tab,换行)。
    $data = stripslashes($data); // 去除输入数据中的反斜杠 (\\)
    $data = htmlspecialchars($data);
    return $data;

?>

<h2>PHP 表单验证实例</h2>
<p><span class="error">* 必需字段。</span></p>
<!--
该表单使用 method="post" 方法来提交数据。
$_SERVER["PHP_SELF"]是超级全局变量,返回当前正在执行脚本的文件名,会发送表单数据到当前页面,而不是跳转到不同的页面。
htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。
预定义的字符是:
& (和号) 成为 &amp;
" (双引号) 成为 &quot;
' (单引号) 成为 &#039;
< (小于) 成为 &lt;
> (大于) 成为 &gt;
-->
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
    <!--"名字"、"E-mail"、"网址"字段为文本输入元素,"备注"字段是 textarea(标签定义多行的文本输入控件)-->
    名字: <input type="text" name="name" value="<?php echo $name;?>">
    <span class="error">* <?php echo $nameErr;?></span>
    <br><br>
    E-mail: <input type="text" name="email" value="<?php echo $email;?>">
    <span class="error">* <?php echo $emailErr;?></span>
    <br><br>
    网址: <input type="text" name="website" value="<?php echo $website;?>">
    <span class="error"><?php echo $websiteErr;?></span>
    <br><br>
    备注: <textarea name="comment" rows="5" cols="40"><?php echo $comment;?></textarea>
    <br><br>
    <!--"性别"字段是单选按钮-->
    性别:
    <input type="radio" name="gender" <?php if (isset($gender) && $gender=="female") echo "checked";?>  value="female">女
    <input type="radio" name="gender" <?php if (isset($gender) && $gender=="male") echo "checked";?>  value="male">男
    <span class="error">* <?php echo $genderErr;?></span>
    <br><br>
    <input type="submit" name="submit" value="Submit">
</form>

<?php
echo "<h2>您输入的内容是:</h2>";
echo $name;
echo "<br>";
echo $email;
echo "<br>";
echo $website;
echo "<br>";
echo $comment;
echo "<br>";
echo $gender;
?>

</body>
</html>

三、$_SERVER[“PHP_SELF”] 变量的跨站脚本利用与避免

当黑客使用跨网站脚本的HTTP链接来攻击时,$_SERVER["PHP_SELF"]服务器变量也会被植入脚本。
因为跨网站脚本附在执行文件的路径后面$_SERVER["PHP_SELF"]的字符串会包含HTTP链接后面的javascript程序代码。

任何JavaScript代码可以添加在<script>标签中!

黑客可以利用这点重定向页面到另外一台服务器的页面上,用恶意代码修改全局变量或者获取用户的表单数据。

例如要指定以下表单文件名为 “test_form.php”:

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">

如使用URL来指定提交地址 “test_form.php”,将以上代码修改为:

<form method="post" action="test_form.php">

黑客在浏览器地址栏中输入:

http://www.xxx.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

以上的 URL 中,将被解析为如下代码并执行:

<form method="post" action="test_form.php/"><script>alert('hacked')</script>

代码中添加了 script 标签,并添加了alert命令。 当页面载入时会执行该Javascript代码(用户会看到弹出框)。

$_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/&quot;&gt;&lt;script&gt;alert('hacked')&lt;/script&gt;">

以上是关于PHP表单验证及安全的主要内容,如果未能解决你的问题,请参考以下文章

21PHP 表单验证

php表单验证

PHP 表单验证

php安全编程

PHP面试题精讲—从Yii2源码ActiveForm看如何安全处理表单验证

PHP面试题精讲—从Yii2源码ActiveForm看如何安全处理表单验证