Transferred from https://security.drupal.org/node/134653 since this was determined to be a feature request for FAPI, as opposed to a security vulnerability.
Problem/Motivation
Example 1 reported by hejazee
==================
some form validators should take precedence. for example the validator should be executed first.
and if it fails, other validators should not be executed.
because form validators set messages on the form.
and if the initial validation fails, the user (attacker bot) should not see if other fields are valid since this could expose unwanted information.
Example 2 reported by jpcondon (private issue)
==================
This module has a denial of service vulnerability.
You can see this vulnerability by:
1. Install Drupal.
2. Create content type with file field with two different restrictions on it, such as file size and file type.
3. Upload file with wrong file type and wrong file size and observe that both error messages appear.
While this isn't a big deal when simply validating file type or size, this presents a larger issue when using a module like the ClamAV module where it will attempt to scan the file even if other file validation errors have occurred. If a file is excessively large it will still be scanned which could cause a denial of service on the website.
Proposed resolution
Create a cancel validation variable, getter, and setter in the form state to track whether subsequent form validation functions should be skipped, i.e. if it is preferred that further validation functions should be prevented from executing, e.g.: you might set setValidationCanceled(TRUE) if a CSRF token is not valid, because it doesn't make sense to perform any further validation (and it might be a security risk to do so).
Remaining tasks
Decide how to add this feature in a backward-compatible way.
Commentary from @David_Rothstein:
There probably isn't a way to actually prevent other validation functions from running currently, but there should be some ways to prevent their error messages from displaying... Here's what I wrote elsewhere:
I don't think we necessarily need a change to Drupal core for this. I haven't looked too deeply into it, but couldn't you at least use something like form_get_errors(), form_set_error(), and form_clear_error() to clear out all validation errors on the form (at the end of the validation process) and then re-set the ones from the desired field only? I think something like this technique might work for both Drupal 6 and Drupal 7.
Also for Drupal 7 there's $form_state['triggering_element']['#limit_validation_errors'] which is a cleaner way to tell Drupal to ignore (and not display) certain form validation errors, but perhaps there's no place in the code where you can set that during form validation and have it work on the rest of the validation... not sure.
User interface changes
n/a
API changes
Some new public functions to handle cancellation:
- FormValidator::cancelValidation
- FormStateInterface::setValidationCanceled
- FormStateInterface::isValidationCanceled
See change record for more details.
Data model changes
n/a