php-过滤、清理电子邮件是否毫无意义?

php-过滤、清理电子邮件是否毫无意义?,php,xss,Php,Xss,我只是创建了一个登记表,我只想把有效和安全的电子邮件插入数据库 一些网站(包括W3学校)建议在运行FILTER\u VALIDATE\u电子邮件之前运行FILTER\u SANITIZE\u电子邮件以确保安全;但是,这可能会将提交的电子邮件从无效更改为有效电子邮件,这可能不是用户想要的,例如: 用户有电子邮件地址jeff@gmail.com,但意外地插入了jeff“@gmail.com 过滤\u清理\u电子邮件将删除“制作电子邮件”jeff@gmail.com即使不是用户的实际电子邮件地址,哪一

我只是创建了一个登记表,我只想把有效和安全的电子邮件插入数据库

一些网站(包括W3学校)建议在运行FILTER\u VALIDATE\u电子邮件之前运行FILTER\u SANITIZE\u电子邮件以确保安全;但是,这可能会将提交的电子邮件从无效更改为有效电子邮件,这可能不是用户想要的,例如:

用户有电子邮件地址jeff@gmail.com,但意外地插入了jeff“@gmail.com

过滤\u清理\u电子邮件将删除“制作电子邮件”jeff@gmail.com即使不是用户的实际电子邮件地址,哪一个过滤器\u VALIDATE\u电子邮件也会说是有效的

为了避免这个问题,我计划只运行FILTER\u VALIDATE\u电子邮件。(假设我不打算输出/处理任何宣布无效的电子邮件)

这将告诉我电子邮件是否有效。如果是,则不需要将其通过过滤器\u清理\u电子邮件,因为任何非法/不安全字符都会导致电子邮件返回无效,对吗

我也不知道有哪封被FILTER_VALIDATE_电子邮件批准为有效的电子邮件可以用于注入/xss,因为空格、括号()和分号会使电子邮件无效。还是我错了

(注:除此之外,我将使用准备好的语句插入数据,我只是想澄清一下)

这样做的“正确”方式是要求用户发送两次电子邮件(这是常见/良好的做法)。但要回答你的问题,
过滤电子邮件并不是毫无意义的。它是一个过滤邮件的过滤器,它的工作做得很好


您需要了解返回
true
false
的筛选器,而实际修改给定变量的筛选器。这两个变量的作用并不相同。

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

$cleanfield = filter_var($field, FILTER_SANITIZE_EMAIL);

if ($cleanfield != $field){
    return FALSE;
}

下面是如何只插入有效的电子邮件

<?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. 
}
PHP是开源的,所以这些问题只要使用它就很容易回答

:

/*{{{{php\u filter\u电子邮件*/
#定义安全“$-。+”
#定义额外的“!*”(),“
#定义国家“{}\\\^~[]`”
#定义标点符号“\%\”
#定义保留“;/?:@&=”
作废php过滤器电子邮件(php输入过滤器参数)
{
/*检查rfc 822的第6节http://www.faqs.org/rfcs/rfc822.html */
const unsigned char allowed_list[]=Low Alpha HIALPHA DIGIT“!#$%&'*+-=?^ `{124;}~@[];
过滤图;
过滤器映射初始化(&map);
筛选映射更新(&map,1,允许的映射列表);
筛选映射应用(值和映射);
}    
:

void php\u filter\u validate\u email(php\u INPUT\u filter\u PARAM\u DECL)/*{{*/
{
(2)目前,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(?:\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]。(?:\\x5C[\\x00-\\x7F]))*\\(2)2)2)以下(2)2)主要(2)以下(2)以下(2)以下(2)以下(2)主要:(3)以下(2)以下(2)以下)主要(2)主要(2)以下(2)主要(2)主要(2)以下以下)主要(2)主要(3)以下以下以下(3)以下以下(3)主要:(:(:(:(3)以下以下以下以下以下)主要:(:(:(:(3)主要::::::::::::::::::)2(以下以下以下:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::[a-z][a-z0-9]*)(?:(?:[a-z][a-z0-9]*)(?:(?:[a-z0-9]+)(?:-+[a-z0-9]+)(?:-+[a-z0-9]+)*)|(?:\[(?::以下::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::(((((((::::::::[a-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-10-0-10-0-10-10-10-10-9[[[[[[10-0-0-0-0-10-10-10-10-10-9[[[[[[[[[[10-0-0-0-9[(?:(?:(?:[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 1,4}:25})[0-5][0-9])(?: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_选项=0;
int-ovector[150];/*需要是3的倍数*/
整数匹配;
/*根据RFC 2821,电子邮件地址的最大长度为320个八位字节*/
如果(Z_STRLEN_P(值)>320){
返回\验证\失败
}
re=pcre_get_compiled_regex((char*)regexp,&pcre_extra,&preg_options TSRMLS_CC);
如果(!re){
返回\验证\失败
}
matches=pcre_exec(re,NULL,Z_STRVAL_P(值),Z_STRLEN_P(值),0,0,ovector,3);
/*0表示向量太小,无法容纳所有捕获的子字符串偏移*/
如果(匹配<0){
返回\验证\失败
}
}

这两者的作用并不相同。
这正是问题的一部分所述。这并不能解决所问的问题。
使用验证过滤器(如
filter\u validate\u EMAIL
)过滤var
不会返回
true
false
。这是误导。验证过滤器不会返回所有返回布尔值。例如,数字1返回数字。
验证正在测试电子邮件的格式是否有效。清理是为了清除电子邮件中的错误字符。
这是问题的一部分。这个答案没有解决问题。好的,足够公平@Izkata。答案已更新,因此他只能插入valid电子邮件。你能举一个例子,清楚地说明一封电子邮件如何通过验证吗?你的第一个区块似乎只有在电子邮件无法通过验证时才能通过,或者我遗漏了一些明显的东西吗?如果是这样的话,为什么首先要进行清理?看起来是多余的。好的,添加了一个例子,清楚地说明了这一点显示了应该如何使用消毒。在第一个例子中,我重点讨论了它们返回的内容与应该如何使用。谢谢
<?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
}
/* {{{ 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);
}    
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
}

}