首页 > 解决方案 > 我的 PHP 表单对垃圾邮件发送者和黑客安全吗?

问题描述

我从 W3schools 写了一个 PHP 脚本。该脚本是检查表单提交的值。所以我修改它以检查值并将它们作为电子邮件发送。我想问一下脚本是否足够安全?这样垃圾邮件发送者和黑客就无法使用它。

代码的第一部分是验证输入的值是否正确。

<?php
    require_once 'includes/header.php'
?>

<?php
 
    $nameErr = $emailErr = $predmetErr = $textErr = "";
    $name = $email = $predmet = $text = "";
    $myMail = "example@example.com";

    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        if (empty($_POST["name"])) {
          $nameErr = "Name is required";
        } else {
          $name = test_input($_POST["name"]);
          if (!preg_match("/^[a-zA-Z-' ]*$/",$name)) {
            $nameErr = "Only letters and white space allowed";
            $name = "";
          }
        }
      
        if (empty($_POST["email"])) {
          $emailErr = "Email is required";
        } else {
          $email = test_input($_POST["email"]);
          if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $emailErr = "Invalid email format";
            $email = "";
          }
        }
      
        if (empty($_POST["predmet"])) {
          $predmetErr = "vyplnte pole";
          $name = "";
        } else {
          $predmet = test_input($_POST["predmet"]);
        }
      
        if (empty($_POST["text"])) {
          $textErr = "vyplnte pole";
          $name = "";
        } else {
          $text = test_input($_POST["text"]);
        }
    }

    function test_input($data) {
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        return $data;
        
    }

?>

这是表单的html代码。

<h2>Form test</h2>
<form  method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
    <input type="text" name="name">
    <span class="error">* <?php echo $nameErr;?></span>
    <input type="text" name="email">
    <span class="error">* <?php echo $emailErr;?></span>
    <input type="text" name="predmet">
    <span class="error">* <?php echo $predmetErr;?></span>
    <textarea name="text" cols="30" rows="10"></textarea>
    <span class="error">* <?php echo $textErr;?></span>
    <button type="submit" name="submit">ODESLAT</button>

</form>

如果一切正确,将发送一封电子邮件。

<?php

if(empty($name)){
  echo "wrong characters";
} else{
  if(empty($email)){
    echo "wrong characters";
  } else{
    $message = "Mail from ". $name . "\n\n". $text;
    mail($myMail, $predmet,$message);
    echo "email send";
  }
}



?>

<?php
    require_once 'includes/footer.php';
?>

标签: phphtmlformsphpmailer

解决方案


这里有很多错误。

默认情况下,表单的操作是当前 URL,因此您不需要设置该action属性。

有一个email输入类型,使用它:

<input type="email" name="email">

安德烈、佐伊和芬会为此感到不安:

if (!preg_match("/^[a-zA-Z-' ]*$/",$name)) {

你的test_input函数需要递归才能有效地清理多重编码的内容,但在大多数情况下,你不需要做它正在做的事情:为什么要htmlspecialchars在非 HTML 上下文中应用?

当您过滤输入时,您并没有转义输出,这一个适合 htmlspecialchars 的地方。

“错误字符”错误消息没有提供足够的上下文——用户无法说出他们做错了什么。

您正在使用该mail()功能,无论如何它都有安全问题,并且正确格式化电子邮件非常困难 - 您没有创建任何必需的标题,构建正确的消息格式(您使用了错误的换行符:电子邮件需要\r\n,尽管邮件功能有时可以处理),并且您很容易受到标头注入攻击。您没有检查 mail(0 函数的返回值,因此当您返回“电子邮件发送”消息时,您不知道它是否有效。

你从 W3Schools 获得这段代码并不让我感到惊讶,它以糟糕的代码而闻名(尽管他们非常擅长 SEO!)。您最好使用一个库,例如您标记此问题的 PHPMailer(披露:我是维护者)。


推荐阅读