代码之家  ›  专栏  ›  技术社区  ›  Alessandro

阻止php中的邮件注入截取某些字符\r\n、\n、%0A、%0D

  •  2
  • Alessandro  · 技术社区  · 8 年前

    我想阻止人们使用php中用于邮件注入的特殊字符发送垃圾邮件。例如 \n \r 用于连接多个标头,因此 %0A %0D 。所以我写了一个正则表达式来匹配它们。但我怀疑我的正则表达式没有那么高效……有些东西让我觉得我在写一些无法使用的东西……感谢任何帮助,谢谢。

    下面是我想做的一个基本示例。。。

    if (!preg_match('/^[^\s]./', $_POST['name']) || (preg_match('/(%0A|%0D|\\n+|\\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $_POST['name'])) || !(strpos($_POST['name'],'\r') === false) || !(strpos($_POST['name'],'\n') === false)) {
      exit("Warning: your Name contains illegal characters! This mail will not be sent!");
    } elseif (!preg_match('/^[^\s]./', $_POST['subject']) || (preg_match('/(%0A|%0D|\\n+|\\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $_POST['subject'])) || !(strpos($_POST['subject'],'\r') === false) || !(strpos($_POST['subject'],'\n') === false)) {
      exit("Warning: your Subject contains illegal characters! This mail will not be sent!");
    } elseif (!preg_match('/^[a-zA-Z0-9]+([_\\.-][a-zA-Z0-9]+)*'.'@([a-zA-Z0-9]+([\.-][a-zA-Z0-9]+))+$/', $_POST['mail'])) {
      exit("Warning: your Mail contains no valid email address! This mail will not be sent!");
    } elseif (!preg_match('/^[^\s]./', $_POST['message'])) {
      exit("Warning: your Message connot be empty! This mail will not be sent!");
    } else {
      $name = $_POST['name'];
      $mail = $_POST['mail'];
      $subject = $_POST['subject'];
      $message = $_POST['message'];
      mail($to, $subject, $message, $headers, "-f$mail") {
      exit("Your Mail is sent! Thanks!");
    }
    

    为了匹配 \n个 , \r , %0年 %0天 我应该如何编写正则表达式?

    !(strpos($_POST['subject'],'\r') === false) !(strpos($_POST['subject'],'\n') === false)

    很好吗?

    谢谢

    2 回复  |  直到 5 年前
        1
  •  2
  •   Alessandro    5 年前

    我做了一个测试。测试结果成功!我直接在中测试了regex localhost 使用不同的方法:

    <?php
    $test = "the dog \n was \r sleeping on the floor";
    if (preg_match_all('/(%0A|%0D|\\n+|\\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $test, $tmp)) {
      echo "I found this character: '";
      print_r($tmp[1]);
      echo "'";
    } else {
      echo "I cannot find any string searched";
    }
    ?>
    

    结果:

    I found this character: 'Array ( [0] => [1] => ) '
    

    查看源代码,我可以看到\n和\r

    I found this character: 'Array
    (
        [0] => 
    
        [1] => 
    )
    '
    

    所以我认为正则表达式构建得很好。

    还有我做的其他测试 strpos() :

    if !(strpos($_POST['subject'],'\n') === false)) {
    

    查找带双引号的\n时,单引号失败。。。

    if !(strpos($_POST['subject'],"\n") === false)) {
    

    结论:regex格式良好 strpos() 需要“”匹配\n或\r。

        2
  •  0
  •   Ajjay Arora    8 年前

    我对regex不太了解,但我可以通过提供一个替代的技巧解决您的问题来帮助您。

    您可以使用以下代码来解决您的目的。

    <?php
    
    function sanitize_strings($raw_string) {
        return preg_replace("/[^0-9a-zA-Z_\-\\\%]+/", "", $raw_string);
    }
    
    if( $raw_string == sanitize_strings($raw_string) )
    {
        echo "No illegal characters found.";
    }
    else
    {
        echo "Illegal characters found.";
    }
    
    ?>
    

    希望这对你有用