表单输入过滤和验证中的黑名单与白名单

ult*_*ohn 6 validation whitelist filter blacklist

哪种是清理用户输入的首选方法?

谢谢你!

inf*_*rno 3

我认为白名单是理想的方法,但是我从未遇到过真正的白名单 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)