2013年07月

入力値検証の目的は「ユーザビリティ」と「システムの信頼性」の向上

ゆうべ寝床で思いついた意見。さっそくブログに書こうと、誰か他に言っている人がいないか調べたら、徳丸本の76ページに思いっきり書いてあった。

すなわち、入力値検証の目的は以下の通りです。

  • 入力値の間違いを早期に発見して再入力を促すことにより、ユーザビリティ(使いやすさ)を向上する
  • 間違った処理を継続することによるデータの不整合などを防ぎ、システムの信頼性を向上させる

もう、これでFAじゃないですか。精読してない俺の馬鹿。

たとえば、ユーザ登録フォームでパスワードが未入力だった場合、アプリケーションは「登録処理に失敗しました」などという曖昧なものではなく「パスワードは必須です」のような明確なメッセージを返すべきだ。それがユーザビリティの向上。

DBにおかしな値が登録されないようにすべきなのは言わずもがな。Railsのドキュメントに「Validations are used to ensure that only valid data is saved into your database.」とある通り。これが信頼性の向上。


ちなみに、このドキュメントには、以下のようにも書かれている。

  • Model-level validations are the best way to ensure that only valid data is saved into your database.
  • Controller-level validations can be tempting to use, but often become unwieldy and difficult to test and maintain. Whenever possible, it's a good idea to keep your controllers skinny, as it will make your application a pleasure to work with in the long run.
  • It's the opinion of the Rails team that model-level validations are the most appropriate in most circumstances.

なので、Railsがコントローラでのバリデーションを推奨するようになったというのはデマです。


入力値のなかには、DBと無関係なものもありうる。「HTML文書のURLを入力するとtitle要素の文字列が返るAPI」を想像すると分かりやすいだろうか。入力値がURL形式であれば、そのURLにアクセスし、ドキュメントをパースするだけ。

こうした、DBと無関係な入力値は、コントローラでバリデーションしてもよいように思える。ただ、少なくともRailsの流儀では、ActiveModel::Modelをインクルードしたモデルでバリデーションするのが普通っぽい。まあ、いずれにしても趣味の問題だろう。


徳丸本の72ページに「文字エンコーディングの妥当性検証を行う理由は、文字コードを使った攻撃手法があるからです」とあるが、ここはしっくりこない。「入力値検証の一部」あるいは「入力値検証の前提」(文字エンコーディングの妥当性を検証しないと、入力値を正しく検証できない)という説明ではダメなんだろうか。

各種インジェクション攻撃やらディレクトリ・トラバーサル攻撃やらについては、それらが起きそうな場所で、文字エンコーディングの妥当性検証を行えばよいわけだし、それほど大変なイメージがいまだに持てないんですよね。しつこくてすみません。

大垣さんと徳丸さんのパリデーション論争の感想

いずれの論点においても、ぼくは徳丸さんのご主張に共感するものだけれど、論争に参戦し、大垣さんを説得しようとは思わない。だって無理だもの。

人生は短いので、無理なことは極力避けたい。ぼくが徳丸さんだったら、PHP入門書の執筆を優先させることだろう。

追記(2013-07-24)

はっきりいえば、徳丸さん(あるいは徳丸さんの主張に賛同するもの)の戦うべき相手は、大垣さんではなく、彼が拠り所としている団体や規格、つまり「世界の常識」そのものなんじゃないかと思うんですよね。それらを引っくりかえせば、大垣さんの主張は根拠がなくなる。

敵が大きすぎて手に負えない、ということなら、ひとまず戦いは諦めて、「世界の常識」を無思慮に信じてしまいかねないWebアプリ開発者(特に初心者)を地道に啓蒙していくしかないんじゃないか。

それには、多少センセーショナルなキャンペーンが必要かもしれない。「駄目なセキュリティ文書の見分け方・その1=ホワイトリスト方式を推奨しているが肝心のホワイトリストが何なのか定義していない」など、Webアプリ開発の初心者でも理解できて、すぐに実践できるような。

記事検索
Twitter