Я думаю, что белый список является желаемым подходом, однако я никогда не встречал реальную проверку HTML-форм в белом списке. Например, вот форма Symfony 1.x с проверкой из документации :
class ContactForm extends sfForm
{
protected static $subjects = array('Subject A', 'Subject B', 'Subject C');
public function configure()
{
$this->setWidgets(array(
'name' => new sfWidgetFormInput(),
'email' => new sfWidgetFormInput(),
'subject' => new sfWidgetFormSelect(array('choices' => self::$subjects)),
'message' => new sfWidgetFormTextarea(),
));
$this->widgetSchema->setNameFormat('contact[%s]');
$this->setValidators(array(
'name' => new sfValidatorString(array('required' => false)),
'email' => new sfValidatorEmail(),
'subject' => new sfValidatorChoice(array('choices' => array_keys(self::$subjects))),
'message' => new sfValidatorString(array('min_length' => 4)),
));
}
}
То, что вы не видите, это то, что он принимает новые входы без настроек проверки и не проверяет наличие входов, которые не зарегистрированы в форме. Так что это проверка ввода в черный список. По белому списку вы сначала определяете входной валидатор, и только после этого привязываете поле ввода к этому валидатору. При таком подходе к «черному списку» легко забыть добавить валидатор к входу, и без этого он прекрасно работает, поэтому вы не заметите уязвимость, только когда станет слишком поздно ...
Гипотетический подход из белого списка будет выглядеть примерно так:
class ContactController {
/**
* @input("name", type = "string", singleLine = true, required = false)
* @input("email", type = "email")
* @input("subject", type = "string", alternatives = ['Subject A', 'Subject B', 'Subject C'])
* @input("message", type = "string", range = [4,])
*/
public function post(Inputs $inputs){
//automatically validates inputs
//throws error when an input is not on the list
//throws error when an input has invalid value
}
}
/**
* @controller(ContactController)
* @method(post)
*/
class ContactForm extends sfFormX {
public function configure(InputsMeta $inputs)
{
//automatically binds the form to the input list of the @controller.@method
//throws error when the @controller.@method.@input is not defined for a widget
$this->addWidgets(
new sfWidgetFormInput($inputs->name),
new sfWidgetFormInput($inputs->email),
new sfWidgetFormSelect($inputs->subject),
new sfWidgetFormTextarea($inputs->message)
);
$this->widgetSchema->setNameFormat('contact[%s]');
}
}