Not much to go on but this warning appears occasionally in watchdog

Warning: preg_grep(): Unknown modifier 'b' in login_security_validate() line 235

Comments

izmeez created an issue. See original summary.

wsantell’s picture

This is occurring on lines 235 and 236 when the username contains a forward slash, as the name is being put into the preg_grep call and made into part of the regex. This has a forward slash for an opening delimiter, so a slash will cause anything following it to be interpreted as a PCRE modifier. For example, with "i/am/a/bad/man" the regex on line 235 becomes:
"/<a href=\"\/user\/password\?name=i/am/a/bad/man\">Have you forgotten your password\?<\/a>/"

Since $name isn't used after line 236 in the login_security_validate function, the easiest solution is to escape any slashes in $name, like so:
$name = str_replace('/', '\/', ($name));
(Insert at line 235)

You could also use this instead, if you think it's more elegant:
$name = addcslashes($name, '/');

wsantell’s picture

This will also occur in the 8.x branch, on lines 200-201 in 8.x (1.2 and dev) - the same solution will work if inserted at line 200

wsantell’s picture

After submitting this I realized that it might be possible to submit other escape characters. I tested this and found that all the PCRE meta-characters are URL-encoded in the error message and causes any matching to fail (except the period, but I don't think that can cause an issue). For example, preg_grep will compare the backslash against %5C and fail.

Due to this, $password_message and $block_message can't be populated, and if the negations are removed in this issue then the message hiding and attempts notification will be bypassed.

I think that the better option would be to ignore the $name value and match on known text, changing lines 235-236 to:

    $password_message = preg_grep("/Have you forgotten your password/", $messages['error']);
    $block_message = preg_grep("/has not been activated or is blocked./", $messages['error']);

However, if there is any possibility those strings can exist in any other error message and not be valid for the purpose of these variables, this revision of the original codefix I submitted appears to work (inserted at line 235:
$name = str_replace('%2F', '\/', urlencode($name));

salvis’s picture

Status: Active » Closed (outdated)

Thank you for the analysis. A more comprehensive fix is in #2941630: Fix the login failure error message detection.