Этот файл php mailer защищен от инъекционных атак?

Моя контактная форма PHP недавно использовалась для рассылки спама. С тех пор были приняты некоторые меры безопасности (пожалуйста, обратитесь к комментариям ниже), и я стремлюсь к коллективной мудрости других, чтобы просмотреть код и убедиться, что он защищен от инъекционных атак.

Заранее спасибо, что нашли время для обзора.

<?php

/* method for validate each input values in case any injection scripts it will ignore */

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

/* honeypot - if hidden field is completed discard form content */

if(!isset($_POST['honeypot']) || $_POST['honeypot'] != '')
{
     die("You spammer!\n");
}
else
{
     // define variables and set to empty values
    $subject = $id = $subcategory = $subcategory = $subcategory_email = $to = $descError = $error =
    $remarks = $response= $message= $name = $from = $phone ="";

if(isset($_REQUEST['category']) && $_REQUEST['category']!="")
{
       //validate each input values for any injection attacks 
        $id = test_input($_REQUEST['category']);            
        $subcategory = test_input($_REQUEST['subcategory']);

             $emails = array
      (
      array("0",""),
      array("1","email1@yahoo.com","email2@yahoo.com"),
      array("2","email1@yahoo.com","email2@yahoo.com"),
      array("3","email1@yahoo.com","email2@yahoo.com"),
      array("4","email1@yahoo.com","email2@yahoo.com"),
      array("5","email1@yahoo.com","email2@yahoo.com")
      );
            $value = explode(",", $subcategory);                  
            $subcategory_email = $emails[$id][$value[0]];

            $remarks = test_input($_REQUEST['remarks']);

        $message = '<html><body>';
        $message .= '<table rules="all" style="border-color: #666;" border="1" cellpadding="10">';
        $message .= "<tr style='background-color:#F5F5F5;'><th width=25%>Heading </th><th width=75%>Content</th></tr>";
        $message .= "<tr><td><b>Category </b></td><td>".$category[$id-1]."</td></tr>";
        $message .= "<tr><td><b>SubCategory </b></td><td>".$value[1]."</td></tr>";
        $message .= "<tr><td><b>Comments</b></td><td><pre>".$remarks."</pre></td></tr>";                    


        if($response==0)
        {
             $name = test_input($_REQUEST['name']);  
            $from = test_input($_REQUEST['email']);

            if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$from)) 
            {
                $emailErr = "Invalid email format";
            }

             $phone = test_input($_REQUEST['phone']);
            $message .= "<tr><td><b>Would you like a response?  </b></td><td>Yes</td></tr>";

            $message .= "<tr><td><b>Name</b></td><td>".$name."</td></tr>";
            $message .= "<tr><td><b>E-Mail</b></td><td>".$from."</td></tr>";
            $message .= "<tr><td><b>Telephone</b></td><td>".$phone."</td></tr>";
        }
        else
        {
            $from = "noreply@test.com";
            $message .= "<tr><td><b>Would you like a response? </b></td><td>No</td></tr>";
        }

        $subject = "SubCategory ".$value[1];       
        //Normal headers
       $headers = "From: " . strip_tags($from) . "\r\n";
$headers .= "Reply-To: ". strip_tags($subcategory_email) . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

        $message .= "</table>";

       if(mail($subcategory_email, $subject, $message, $headers))
       {           
           include("thanks.php");
            $error=6;
       }
       else
       {
           echo "mail not sent";
       }
}
else
{
    echo "<br/>";
    $subject = "Sub Category";

    $to = "Email1@yahoo.com";        
    if(empty($_REQUEST['remarks']))
    {
      $descError = "Enter Description";   
      $error = 5;
    }
    else
    {
          $remarks = test_input($_REQUEST['remarks']);
    }               

   if(test_input($_REQUEST['response'])=="0")
    {       
        $yesDIV = "checked";
        $response = "Yes";
    if(empty($_REQUEST['name']))
    {
      $nameError = "Name Required"; 
        $error = 5;   
    }
    else
    {
        $name = test_input($_REQUEST['name']);
    }
    $from = $_REQUEST['email'];
    if(empty($_REQUEST['email']))
    {
      $emailError = "Email Required";
          $error = 5;     
    }
        else if (!filter_var($from, FILTER_VALIDATE_EMAIL)) {
    $emailError = "Valid Email Required";
          $error = 5;   
}
    }
    else
    {
      $noDIV = "checked";
      $response = "No";
      $bodyDIV = "style='display:none;'";
    }

if($error!=5)
{   
     $phone = test_input($_REQUEST['phone']);

    $message = '<html><body>';

        $message .= '<table rules="all" style="border-color: #666;" border="1" cellpadding="10">';
        $message .= "<tr style='background-color:#F5F5F5;'><th width=25%>Heading </th><th width=75%>Content</th></tr>";
        $message .= "<tr><td><b> Comments</b></td><td ><pre>".$remarks."</pre></td></tr>";    
    $message .= "<tr><td><b>Would you like a response?  </b></td><td>".$response."</td></tr>";

    $message .= "<tr><td><b>Name</b></td><td>".$name."</td></tr>";
    $message .= "<tr><td><b>E-Mail</b></td><td>".$from."</td></tr>";
    $message .= "<tr><td><b>Telephone</b></td><td>".$phone."</td></tr>";
    $message .= "</table>";
     //Normal headers
       $headers = "From: noreply@test.com \r\n";
$headers .= "Reply-To: ". strip_tags($from) . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

    if(mail($to, $subject, $message, $headers))
       {           
           include("thanks.php");
           $error=6;
       }
       else
       {
           echo "mail not sent";
       }
}
}
}
?>

1 ответ

Решение

Термин "внедрение" относится к внедрению кода, причем код относится к любому компьютерному языку. Поскольку каждый компьютерный язык различен, проблемы и решения также различны, и их необходимо решать отдельно для каждого языка. Тем не менее, у вас есть универсальная функция, которая пытается предотвратить все виды инъекций одновременно и, часто, используя худший метод: удаление пользовательских данных.

Например:

$headers = "From: " . strip_tags($from) . "\r\n";

Какой смысл брать адрес электронной почты и удалять из него теги HTML для создания заголовка электронной почты?

$data = htmlspecialchars($data);

Вы применяете это, например, к $_REQUEST['email'], Почему вы хотите вставить HTML-сущности в адрес электронной почты?

В вашем коде я вижу два потенциальных источника для инъекций:

  • HTML - когда вы вводите пользовательские данные в HTML, вам необходимо убедиться, что пользовательские данные обрабатываются как простой текст (т.е. все, что набрал пользователь, не отображается как HTML). Ты можешь использовать htmlspecialchars(), Вы вроде как делаете это, но в этом действительно трудно быть уверенным.

  • Заголовки электронной почты - mail()Четвертый аргумент позволяет определить заголовки почты. Ввод необработанного пользовательского ввода туда (что, возможно, и происходит сейчас) позволяет скрыть полное тело сообщения, заменить его чем-либо другим и даже выбрать новых получателей. По сути, вам нужно удалить новые строки (опять же, трудно сказать, правильно ли вы это делаете...).

Отправка электронной почты с помощью PHP - это сложно. Лучше пропустить старое доброе mail() и использовать стороннюю библиотеку, такую ​​как PHPMailer или Swift Mailer.

Другие вопросы по тегам