ZF-2547: Validator displays password for field types of 'password'

Description

Creating a form with a password field that has a validator will cause the password to be printed on the screen in an error message if the password supplied fails validation.

Form from Config [default] action=/ method=post elements.username.type = "text" elements.username.options.label = "Username" elements.username.options.validators.alnum.validator = "alnum" elements.username.options.validators.regex.validator = "regex" elements.username.options.validators.regex.options.pattern = "/^[a-z]/i" elements.username.options.validators.strlen.validator = "StringLength" elements.username.options.validators.strlen.options.min = "6" elements.username.options.validators.strlen.options.max = "20" elements.username.options.required = true elements.username.options.filters.lower.filter = "StringToLower" elements.password.type = "password" elements.password.options.label = "Password" elements.password.options.validators.strlen.validator = "StringLength" elements.password.options.validators.strlen.options.min = "6" elements.password.options.validators.strlen.options.max = "20" elements.password.options.required = true elements.submit.type="submit"

IndexController::indexAction() $formConfig = new Zend_Config_Ini('form.login.ini', 'default');

    $form = new Zend_Form($formConfig);
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        echo $form->isValid($_POST)?'Valid':'Not Valid';
    }
    $this->view->form = $form;

If the password is entered as "asdf" the error prints out as

'asdf' is less than 6 characters long

This can (and should) be viewed as a security risk. The password should be left blank if a validator is used for a password field.

Comments

Updating to include the Zend_Validate component, as this isn't specific to Zend_Form.

A number of validators include the original value passed to them when creating error messages. We should likely have a way to suppress such functionality on demand; if we did, the Password form element could set this on validators prior to running isValid().

One possibility is to modify Zend_Form_Element_Password::getMessages() to strip out the value:


// use raw value, as that is what is sent to validator
$value    = $this->getRawValue();
$messages = array();
foreach ($this->_messages as $key => $message) {
    $messages[$key] => str_replace($value, '', $message);
}
return $messages;

While not an ideal solution, it would likely only be used once per request. It is prone to potential error.

For now, you can very easily modify the messages by passing a 'messages' option to the validator options, with key value pairs of error codes => messages (this can be done from a config, as well).

Additionally, you can use a Zend_Translate_Adapter to translate error codes to messages; when you attach a translate adapter to a form, it will then translate the error messages accordingly.

Yeah, I've used my own code to work around that with deployable code, but now that it's being merged with what will probably be a very popular module (Building forms from a config file = brilliant) I think it would be a good idea to have a way to hide the password. I can help out with that, of course, but I think it would be prudent to have it added before 1.5 goes GA.

I would suggest substituting *'s for each character in the $value string as the default. Seeing

'****' is less then 6 characters long

seems more intuitively understandable for the user then

'' is less then 6 characters long

which suggests a programming problem in my opinion.

Done as of r7916.