|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-12-13 11:55 UTC] kaulkwappe dot php-bugs at prvy dot eu
Description: ------------ --- From manual page: https://php.net/filter.filters.validate --- Test script: --------------- $email = 'php-announce-sc.123456.abcabcabcabcabcabc-abcabcabc-php=example.com@lists.php.net'; var_dump(filter_var($email, FILTER_VALIDATE_EMAIL)); Expected result: ---------------- Should return validate and return the string. Actual result: -------------- Does not validate. Returns > bool(false) PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 21:00:02 2025 UTC |
looking at the source code: #define SAFE "$-_.+" #define EXTRA "!*'()," #define NATIONAL "{}|\\^~[]`" #define PUNCTUATION "<>#%\"" #define RESERVED ";/?:@&=" void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL) { 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); } it appears to be not correct.... I would think it would be: #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); }But I would do a #define EMAIL_ADDR "@." so that the function would look like: #define SAFE "$-_.+" #define EXTRA "!*'()," #define NATIONAL "{}|\\^~[]`" #define PUNCTUATION "<>#%\"" #define RESERVED ";/?:@&=" #define EMAIL_ADDR "@." void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL) {const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT EMAIL_ADDR; filter_map map; filter_map_init(&map); filter_map_update(&map, 1, allowed_list); filter_map_apply(value, &map); } This file (sanitizing_filters.c),has a lot of extra space characters. They should be removed so white space injection isn't a possibility....Keep in mind mail() has a critical flaw: a nested parameter. very bad practice, as the nested parameter can be filled even though the program didn't use it. lets look at mail(): bool mail( string $to, string $subject, string $message [, string $additional_headers [, string $additional_parameters ]] ) $additional_parameters is the weak code and the exploit in the MTA (mail transfer agent)... When PHP is configured with the second option, calls to the mail() function will result in the execution of the configured MTA program. Although PHP internally applies escapeshellcmd() to the program call which prevents an injection of new shell commands, the 5th argument $additional_parameters in mail() allows the addition of new program arguments to the MTA. Thus, an attacker can append program flags which in some MTA’s enables the creation of a file with user-controlled content. vilnerable code: mail("myfriend@example.com", "subject", "message", "", "-f" . $_GET['from']); The code shown above is prone to a remote command execution that is easily overlooked. The GET parameter from is used unsanitized and allows an attacker to pass additional parameters to the mail program. For example, in sendmail, the parameter -O can be used to reconfigure sendmail options and the parameter -X specifies the location of a log file. Proof of concept: example@example.com -OQueueDirectory=/tmp -X/var/www/html/rce.php The proof of concept will drop a PHP shell in the web directory of the application. This file contains log information that can be tainted with PHP code. Thus, an attacker is able to execute arbitrary PHP code on the web server when accessing the rce.php file. Another intuitive approach is to use PHP’s email filter in order to ensure that only a valid email address is used in the 5th parameter of mail(). filter_var($email, FILTER_VALIDATE_EMAIL) However, not all characters that are necessary to exploit the security issue in mail() are forbidden by this filter. It allows the usage of escaped whitespaces nested in double quotes. Due to the nature of the underlying regular expression it is possible to overlap single and double quotes and trick filter_var() into thinking we are inside of double quotes, although mail()s internal escapeshellcmd() thinks we are not. Toxic code: 'a."'\ -OQueueDirectory=\%0D<?=eval($_GET[c])?>\ -X/var/www/html/"@a.php For the here given url-encoded input, the filter_var() function returns true and rates the payload as a valid email address. This has a critical impact when using this function as a sole security measure: Similar as in our original attack, our malicious "email address" would cause sendmail to print the following error into our newly generated shell "@a.php in our webroot. <?=eval($_GET[c])?>\/): No such file or directory Remember that filter_var() is not appropriate to be used for user-input sanitization and was never designed for such cases, as it is too loose regarding several characters.> Remember that filter_var() is not appropriate to be used for > user-input sanitization and was never designed for such cases, > as it is too loose regarding several characters. Thanks for bringing that to mind. I guess following approach would be recommended: $sanitized = \filter_var($email, FILTER_SANITIZE_EMAIL); if ($sanitized === $email && \filter_var($email, FILTER_VALIDATE_EMAIL)) { return true; } return false;We should develop application filters, because the current ones are designed for web page formatting, instead of web-applications. It must be separate from any other functions, including escapeshellcmd() A small addition of these functions would solve things: filter_user_text: only a-z,A-Z,0-9, and !@#$%^&*-+_ are passed, "(){}[]';:'<>,. are encoded to html entitites, but anything below ASCII #32 (space character) and anything above ASCII #126 get escaped.