validation周りについて語るValidation Nightに行ってきたレポ #v_night
12/5にLINEで開催されたValidation Nightに行ってきたのでその時のメモ。
最近なんか勉強会のメモばっかだなw
ちゃんと技術っぽいメモも残すのがんばります。
SecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのか
講演者:@ockeghem様
- Drupal
- 三大CMSの一つ
- 洗礼されている
- secureである
- whitehouse, NASAなどでも使われている
drupalの脆弱性
Drupageddon
- 非常に攻撃しやくて威力が高い
- 侵入したとして想定して対処しましょう
- 10/15 午後11時にDrupal 7.32のパッチを適用してないと攻撃されたと思え!
- 通常時
- http://…/?name=admin&pass=xxx
- 実行SQL
1SELECT * FROM users WHERE name = 'admin' AND status = 1
- 複数のユーザにすると
- http://…/?name[]=user1&name[]=user2
- 実行SQL
1SELECT * FROM users WHERE name IN (:name_0, :name_1) AND status = 1 - bindされる値は’user1′, ‘user2’と展開される
1array(':name_0' =>'user1', ':name_1' => 'user2')
- キー名をつけると
- http://…/?name[id1]=user1&name[id2]=user2
- 実行SQL
1SELECT * FROM users WHERE name IN (:name_id1, :name_id2) - プレースホルダーはエスケープとか出来ない
- 空白をつける
- http://…/?name[1 xxx]=user1&name[]=user2
- 実行SQL
1SELECT * FROM users WHERE name = :name_1 xxx, :name_2 - プレースホルダSQL文として解釈される
- つじつまをあわせる
- http://…/?name[2 ;SELECT sleep(10); –]=…
1SELECT * FROM users WHERE name = :name_2 ; SELECT sleep(10) -- , :name_2
- http://…/?name[2 ;SELECT sleep(10); –]=…
- demo
- Burp Suiteというツールを使ってリクエストを改善してみる
- http://…/?name[1 ;select sleep(20); –]=%name[1]=%pass=xxx…
- その後管理者権限を与えるSQLなどを実行した
- 脆弱なソースの説明
- 対策はbind記述している$iをarray_values($i)に変える
JVNDB-2014-005632
- 100万バイトのパスワードのリクエストを行う
- これだけでapacheのcpuが100%になってしまう
- phpのタイムアウトデフォルト値は30秒でおわるが、並列で来られると死ぬ
- DOS状態になる脆弱性
- ソースの説明
- パスワードを毎回連結しながらハッシュ計算を32768回繰り返している
- 対策はパスワードの長さが512回超えたらぬければいいが。。。validationしろよ
validation
- Drupalは最低限のバリデーションしかしてない
- ユーザの登録の際にはバリでーションはしている
- 徳丸本にかいてあること
- バリデーションはセキュリティのためではないが、セキュリティのために役立つ場合がある
- 脆弱性が発生する箇所で対策を行うようにしよう
- 脆弱性対策はミクロな対策をしよう
- 反論:入力バリデーションは当てにするようなものではない
まとめ
- Drupalのログイン処理ではバリデーションをしていない
- ミクロの対処にこだわっているようにみえる
- バリデーションを拒否する必要もないように思える
- セキュリティ面から見た場合、
- Good: 様々な局面や道の局面で役立つ可能性
- Bad: 脆弱性の根本対策ではない、役に立つとは限らない
- 大垣さんと徳丸さんのバリデーションに関する主張はほとんど同じで常任に区別は不能
- バリデーションは仕様を元にやっておこう。「転ばぬ先の杖」になるかも
FAQ
- バリデーションをするせんびきをどうしてるか?
- バリデーションは常にやるのがいい
- パラメータごとに文字長などのチェックをしよう
RDBにおけるバリデーションをリレーショナルモデルから考える
講演者:@nippondanji様
- SQLインジェクション, 入力バリデーション
- RDB自身の問題ではなく、アプリケーションの問題
- RDB側でバリデーションはいらない、アプリでやってくれ
- リレーショナルモデルにバリデーションはないが、Type ConstraintとDatabase Constraintがある
- ドメインは究極のホワイトリスト!
- 値は想定されたもののみ、集合の要素の一つをとってくるだけ。
- 事前に判明している値ならどれをとっても安全なはず
- 実際にドメインを集合として表現するのは不可能に近い(とくに文字列で表現するデータ)
- 妥協案としてドメインを制約で表現
- SQLで使用できるツール
- CHECK制約 (MySQLできないけど)
- CREATE TYPE
- TRIGGER
- テーブル+外部キー制約
- 制約≒テーブルへ格納するデータをフィルタリングする
- SQLで使用できるツール
- ドメインの設計は超重要
- 正しいデータ型を使えばアプリケーションによるバリデーションの手間が軽減される
- 数値型を使えば取り出すときに数値であるのが保証されてるのでバリデーション不要
- CHECK制約でとり得る値の範囲を絞り込む
- 本当にDBにある値が正しい値か?確認にはコストがかかるので重要なデータにコストを掛ける
SQL ≠ リレーショナルモデル
- リレーショナルモデル
- 集合論に基づくモデル
- SQL
- リレーショナルモデルに基づいたDB操作言語
- リレーショナルモデル以外のデータの扱いおよび操作も可能
- SQLが必要なのはリレーショナルモデルではツリーやグラフなど表現できないときに必要
- リレーショナルモデルに適合するデータとそうでないデータが入り乱れるので適材適所で使う
- RDBにおける制約とバリデーション
- プロシージャ内でPREPAREするべからず
まとめ
- RDBにあるのは制約。バリデーションではない
- RDB周りでバリデーションが必要になる所
- RDBからの出力=アプリケーションへの入力
- リレーショナルモデルに沿わないデータやロジック
- バリデーションについて考えるときもリレーショナルモデルの理解も大事
Javaでのバリデーション 〜Bean Validation篇〜
講演者:@eiryu様
- なぜやるのか
- ヒューマンエラーはつきもの
- 壊れたユーザーデータはマーケティングも生かせない
- webアプリの場合、ユーザー情報漏えいがあるかも
- どうやるか
- Bean Validationを利用
- Webアプリケーションのコントローラでユーザー入力をチェック
- Bean Validationとは…
- 予めよく使う制約が用意されている
- ユーザの入力を受け取るJavaBeans(POJO)にアノテーションで記載するため、POJOに対してテストが出来る
- Constraintsの例:@NotNull, @Pattern, @Size @AssertTrue
- 単項目チェック
- 名前入力必須だが入力されているか
- 相関チェック
- 性別で男性を選択しているのに妊婦の項目にチェックしていないか
- サンプル
- きにすべきポイント/Tips
- 普通に使うと、バリデーションが行われる順番はランダム
- Webアプリケーションでメッセージを丈夫に列挙する場合は注意
- Group, Group sequenceという仕組みを使うとバリデーションの順番を制御することが出来る – メッセージはプロパティファイルに外出し可能
- JavaBeansの中にJavaBeansがあるようなケースではそにフィールドに対して@Validをつけると再帰的にやってくれる
- 普通に使うと、バリデーションが行われる順番はランダム
Webアプリケーション開発におけるValidationの変遷。今日求められているValidationとはなにか?
講演者:@tokuhirom様
- validationの歴史のお話
- validationをどこでやるか
- Client Side/Controler/Model
- Controllerでのバリデーションはすたれている
- jqueryで頑張る時代は大変でしたね
- HTML5 Validation
- 例
1<input type="email" required>
- 管理画面などはこれで十分
- 例
- Modelでのバリデーション中心にしたほうがいいなと思う今日このごろ
- Modelは通らなかったらExceptionをthrow
- Internal Server Errorを出しまくればいいや
- JSON APIの全盛の時代
- clientからきた値をMySQLやRedisにいれたりなど
- 結局Controllerにもバリデーションあったほうがいいなと思ったりしてる
- 入口と出口でバリデーション
- JSONの入力はBeanValidationを使うということにしているが実際は使ってない(それっぽい自作のやつでやってる)
- テストコードを書くときに制約を満たしてレスポンスをかえしているかとのチェックができるのでレスポンスにもバリデーションつけてたりする
- JSON Schemaとか手で書くのは現実的ではない。
- できれば自動生成したいが手が回ってない
- JSONをクラスにマッピングするのはだるいが、クライアント側のコードを補完効かせてバリバリかける
- 最近はmicroservicesが全盛
- Bean Validationでやるのがちょうどいいのでは
FAQ
- コントローラのテストとは?
- JSONのAPIなので、実際にリクエストをなげて値があるかをチェックしたりしてる
- タイトルに特定の文字列が含まれているか程度のチェックをしています
LT: jQueryによるバリデーション最高
講演者:@side_tana様
- jQueryValidationPluginだけだとつらいお話
- かゆいところに手が届く非常にいいプラグイン
- HTML5と同じシンタックスを使えて、いい感じに動く
- \Demoでまさかのvalidation動かない罠でざわめく会場/
- ライヴデバック!かっこいい!
- 動的にinputが追加されるパターン
- 追加するinputに対してvalidationをいれてもnameが変わるようにする
- お互いの値が殴りあうパターン
- サーバサイドとルールが違う!
- サーバサイドのメッセージと殴り合いになる
- まとめ
- ちょっとリッチなバリデーションができるが難しいことやると大変
LT: focuslight-validator で Sinatra Application の ヴァリデーション Focuslight-validator validate sinatra application
講演者:@studio3104様
focuslight-validator validate sinatra application – validation night at LINE corporation from Satoshi Suzuki
- FocuslightはGrowthForecastのRubyクローン
- 今回はFocuslightで使われているFocuslight-validatorの紹介
- 簡単にバリデーションできる
- Built-in rules
- 整数であるか、自然数であるかなどの最初から搭載済みのルール
- 搭載されているルールで解決できなければlamdba ruleを使って解決する
- messageの文字数制限のバリデーションなど、lambaでかいたりする
- 複数のルールを指定することもできるが、順番に注意
- 最後に定義したルールで値がかえってくるので注意
- validation typeいろいろあります
WebApplicationフロントエンドValidation
講演者:@kyo_ago様
- フロントエンドValidationは安全ではない
- セキュリティ的な意味ではなく、ユーザビリティの一種
- パスワード何文字まで入力できるかなど、できるだけ早く間違いに気づいて欲しい
- アプリケーションとしての誓約を行う
- サーバサイドでも同じ制約を行う
- クライアントとサーバでValidationがわかれるなどのロジックの分散はつらい
ValidationAPI
- validation専用APIを作る
- クライアントで入力内容を随時APIに投げる
- サーバでも内部で同じAPIに投げるを使う
- Validationロジックは底に集約する
- 問題点
- リアルタイムでエラーを出したい場合は、毎回通信するのか?
- 頻繁な通信はスマフォ環境だとバッテリー的に辛い
- エラー文言はどこに出す?
- HTML5 form validationとの連携は?
- どこまでをJSで実装するか
- formを出現させるかどうするかとか
- エラー文言どうするか
- 簡単なフォームなら問題ない
- validationをどちらでやるか?
- クライアントサイドもやらなくていいならやりたくない
- サーバサイドにまるなげしたい!
LT: 自作JSライブラリでvalidationをごにょごにょする
講演者:@shigemk2様
- バリデーションといえば正規表現
- 正規表現は面倒、間違えたら死ぬのでライブラリを作った
- https://github.com/shigemk2/regexp-js/
- qunitでテスト書いてます
- grunt使いたかっただけかも
- typoしやすいものはライブラリに押し込んだほうがいいと思いました
LT: Rails Context Validation
講演者:@kbaba1001様
- ウィザードを作ったら画面ごとに異なるバリデーションが必要になった
- validatesメソッド
- railsのifオプションの説明
- with_optionsはoptionをまとめるだけなので入れ子をする意味がなくなる
- unlessオプションを使えばなんとかなる
- 読みにくいし、画面に依存しがち
- onオプション
- コントローラ側でsaveするときにcontextを指定すると、save時に指定したバリデーションが適用される
1Model.save(context: :first_login) - しかし複数指定は出来ない
- コントローラ側でsaveするときにcontextを指定すると、save時に指定したバリデーションが適用される
- 複雑にするならバリデーション用クラスを作ったり、DBテーブルとモデルを分けよう
まとめ
- if,unlessは辛いのでonを使おう
- 設計を見直そう
個人的所感
- drupalのハッキングデモはなかなか面白かった
- validationとかアプリ側の問題で、RDBのvalidationとは一体,,,とおもったが、それでも話をひねり出す@nippondanjiさんが漢すぎる
- Validation APIは案外いいソリューションなのではと思う所存。