我认为白名单是理想的方法,但是我从未遇到过真正的白名单 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)),
));
}
}
Run Code Online (Sandbox Code Playgroud)
您看不到的是,它接受没有验证设置的新输入,并且不会检查未在表单中注册的输入是否存在。所以这是一个黑名单输入验证。通过白名单,您可以首先定义一个输入验证器,然后才将输入字段绑定到该验证器。通过这样的黑名单方法,很容易忘记在输入中添加验证器,并且如果没有验证器,它也可以完美工作,因此您不会注意到该漏洞,只有当为时已晚时......
假设的白名单方法看起来像这样:
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]');
}
}
Run Code Online (Sandbox Code Playgroud)