php - FILTER_SANITIZE_EMAIL毫无意义吗?

Ale*_*lex 24 php xss

我只是创建一个注册表单,我只想将有效和安全的电子邮件插入数据库.

一些站点(包括w3schools)建议在运行FILTER_VALIDATE_EMAIL之前运行FILTER_SANITIZE_EMAIL是安全的; 但是,这可能会将提交的电子邮件从无效的电子邮件更改为有效的电子邮件,这可能不是用户想要的,例如:

用户的电子邮件地址为jeff!@gmail.com,但不小心插入了jeff"@ gmail.com.

FILTER_SANITIZE_EMAIL将删除"使FILTER_VALIDATE_EMAIL认为有效的电子邮件jeff@gmail.com有效,即使它不是用户的实际电子邮件地址.

为避免此问题,我计划仅运行FILTER_VALIDATE_EMAIL.(假设我不打算输出/处理任何声明无效的电子邮件)

这将告诉我电子邮件是否有效.如果是,那么应该没有必要通过FILTER_SANITIZE_EMAIL传递它,因为任何非法/不安全的字符,都会导致电子邮件返回无效,对吗?

我也不知道FILTER_VALIDATE_EMAIL批准的任何可用于注入/ xss的电子邮件,因为空格,括号()和分号会使电子邮件无效.还是我错了?

(注意:我将使用预备语句来插入除此之外的数据,我只想清除它)

jbr*_*ahy 24

以下是仅插入有效电子邮件的方法.

<?php
$original_email = 'jeff"@gmail.com';

$clean_email = filter_var($original_email,FILTER_SANITIZE_EMAIL);

if ($original_email == $clean_email && filter_var($original_email,FILTER_VALIDATE_EMAIL)){
   // now you know the original email was safe to insert.
   // insert into database code go here. 
}
Run Code Online (Sandbox Code Playgroud)

FILTER_VALIDATE_EMAIL并且FILTER_SANITIZE_EMAIL都是有价值的功能并且具有不同的用途.

验证是否测试电子邮件是否为有效格式.消毒是为了清除电子邮件中的坏人物.

<?php
$email = "test@hostname.com"; 
$clean_email = "";

if (filter_var($email,FILTER_VALIDATE_EMAIL)){
    $clean_email =  filter_var($email,FILTER_SANITIZE_EMAIL);
} 

// another implementation by request. Which is the way I would suggest
// using the filters. Clean the content and then make sure it's valid 
// before you use it. 

$email = "test@hostname.com"; 
$clean_email = filter_var($email,FILTER_SANITIZE_EMAIL);

if (filter_var($clean_email,FILTER_VALIDATE_EMAIL)){
    // email is valid and ready for use
} else {
    // email is invalid and should be rejected
}
Run Code Online (Sandbox Code Playgroud)

PHP是开源的,因此只需使用它就可以轻松回答这些问题.

FILTER_SANITIZE_EMAIL的来源:

/* {{{ php_filter_email */
#define SAFE        "$-_.+"
#define EXTRA       "!*'(),"
#define NATIONAL    "{}|\\^~[]`"
#define PUNCTUATION "<>#%\""
#define RESERVED    ";/?:@&="

void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL)
{
    /* Check section 6 of rfc 822 http://www.faqs.org/rfcs/rfc822.html */
    const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT "!#$%&'*+-=?^_`{|}~@.[]";
    filter_map     map;

    filter_map_init(&map);
    filter_map_update(&map, 1, allowed_list);
    filter_map_apply(value, &map);
}    
Run Code Online (Sandbox Code Playgroud)

FILTER_VALIDATE_EMAIL的来源:

void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
{
const char regexp[] = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD";

pcre       *re = NULL;
pcre_extra *pcre_extra = NULL;
int preg_options = 0;
int         ovector[150]; /* Needs to be a multiple of 3 */
int         matches;


/* The maximum length of an e-mail address is 320 octets, per RFC 2821. */
if (Z_STRLEN_P(value) > 320) {
    RETURN_VALIDATION_FAILED
}

re = pcre_get_compiled_regex((char *)regexp, &pcre_extra, &preg_options TSRMLS_CC);
if (!re) {
    RETURN_VALIDATION_FAILED
}
matches = pcre_exec(re, NULL, Z_STRVAL_P(value), Z_STRLEN_P(value), 0, 0, ovector, 3);

/* 0 means that the vector is too small to hold all the captured substring offsets */
if (matches < 0) {
    RETURN_VALIDATION_FAILED
}

}
Run Code Online (Sandbox Code Playgroud)

  • `验证是否测试电子邮件是否为有效格式.消毒是为了清除电子邮件中的坏人物."部分问题已经说明了这一点.这个答案没有解决被问到的问题. (6认同)
  • 用`filter_var($email,FILTER_SANITIZE_EMAIL)`改变用户输入的地址有什么意义?如果提供的电子邮件地址无效,则应拒绝它,而不是通过清理和事后验证盲目“修复”。 (3认同)
  • 能否请您展示一个示例,清楚地说明如何对电子邮件进行消毒以及验证?看来你的第一个阻止只有在无法消毒的情况下才能通过电子邮件,或者我是否错过了一些明显的东西?如果是这样,那么为什么要首先进行消毒?看起来多余. (2认同)
  • 阅读代码,它只插入有效且与原始电子邮件地址匹配的电子邮件。 (2认同)

Dav*_*nco 5

这样做的"正确"方式是要求用户的电子邮件两次(这是常见/良好做法).但回答你的问题,FILTER_SANITIZE_EMAIL并非毫无意义.这是一个清理电子邮件的过滤器,它可以很好地完成工作.

您需要了解验证过滤器验证返回,true或者清理实际上修改给定变量false的过滤器.这两者并没有达到同样的目的.

  • "这两个人没有达到同样的目的.这正是问题的一部分所说的.这并没有解决所提出的问题. (3认同)

Tam*_*inn 5

我读了同一篇文章并想到了同样的事情:简单地改变一个无效的变量是不够的。我们需要实际告诉用户存在问题,而不是仅仅忽略它。我认为,解决方案是将原始版本与经过消毒的版本进行比较。即使用 w3schools 示例,只需添加:

$cleanfield = filter_var($field, FILTER_SANITIZE_EMAIL);

if ($cleanfield != $field){
    return FALSE;
}
Run Code Online (Sandbox Code Playgroud)