如果已经使用 FILTER_VALIDATE_EMAIL,FILTER_SANITIZE_EMAIL 是否毫无意义? [英] Is FILTER_SANITIZE_EMAIL pointless if already using FILTER_VALIDATE_EMAIL?
问题描述
我只是在创建一个注册表单,我只想将有效且安全的电子邮件插入数据库.
I am just creating a registration form, and I am looking only to insert valid and safe emails into the database.
一些网站(包括 w3schools)建议在运行 FILTER_VALIDATE_EMAIL 之前运行 FILTER_SANITIZE_EMAIL 以确保安全;但是,这可能会将提交的电子邮件从无效电子邮件更改为有效电子邮件,这可能不是用户想要的,例如:
Several sites (including w3schools) recommend running FILTER_SANITIZE_EMAIL before running FILTER_VALIDATE_EMAIL to be safe; however, this could change the submitted email from an invalid into a valid email, which could not be what the user wanted, for example:
用户的电子邮件地址是 jeff!@gmail.com,但不小心插入了 jeff"@gmail.com.
The user has the email address jeff!@gmail.com, but accidentally inserts jeff"@gmail.com.
FILTER_SANITIZE_EMAIL 会删除使 FILTER_VALIDATE_EMAIL 认为有效的电子邮件 jeff@gmail.com 的,即使它不是用户的实际电子邮件地址.
FILTER_SANITIZE_EMAIL would remove the " making the email jeff@gmail.com which FILTER_VALIDATE_EMAIL would say is valid even though it's not the user's actual email address.
为了避免这个问题,我计划只运行 FILTER_VALIDATE_EMAIL.(假设我不打算输出/处理任何宣布无效的电子邮件)
To avoid this problem, I plan only to run FILTER_VALIDATE_EMAIL. (assuming I don't intend to output/process any emails declared invalid)
这将告诉我电子邮件是否有效.如果是,则不需要通过 FILTER_SANITIZE_EMAIL 传递它,因为任何非法/不安全的字符是否已经导致电子邮件返回无效,对吗?
This will tell me whether or not the email is valid. If it is then there should be no need to pass it through FILTER_SANITIZE_EMAIL because any illegal/unsafe characters, would've already caused the email to be returned invalid, correct?
我也不知道有任何被 FILTER_VALIDATE_EMAIL 批准为有效的电子邮件可用于注入/xss,因为空格、括号 () 和分号会使电子邮件无效.还是我错了?
I also don't know of any email approved as valid by FILTER_VALIDATE_EMAIL that could be used for injection/xss due to the fact that white spaces, parentheses () and semicolons would invalidate the email. Or am I wrong?
(注意:除此之外,我将使用准备好的语句插入数据,我只是想清除它)
(note: I will be using prepared statements to insert the data in addition to this, I just wanted to clear this up)
推荐答案
以下是仅插入有效电子邮件的方法.
Here's how to insert only valid emails.
<?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.
}
FILTER_VALIDATE_EMAIL
和 FILTER_SANITIZE_EMAIL
都是有价值的功能,用途不同.
FILTER_VALIDATE_EMAIL
and FILTER_SANITIZE_EMAIL
are both valuable functions and have different uses.
验证正在测试电子邮件是否为有效格式.消毒是清除电子邮件中的不良字符.
Validation is testing if the email is a valid format. Sanitizing is to clean the bad characters out of the 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
}
PHP 是开源的,因此只需使用它即可轻松回答这些问题.
PHP is open source, so these questions are easily answered by just using it.
/* {{{ 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
}
}
这篇关于如果已经使用 FILTER_VALIDATE_EMAIL,FILTER_SANITIZE_EMAIL 是否毫无意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!