安全なウェブサイトを作るためにネット上の情報を漁っていると、「入力バリデーション」と「パスワード」についてクリティカルなものがあったりする。今回はこのあたりについて自分の考えをまとめておく。入力バリデーション入力のバリデーションはSQLインジェクションの根本的な対策にはならない。SQLインジェクションへの根本的な対策は、プリペアードステートメントを利用すること。クライアントサイドの入力バリデーションは、ウェブサイトの利用者へ「入力値の条件が満たされていない理由」を親切丁寧に伝えるために過ぎない。攻撃者はその気になればHTTPリクエストのすべての内容を生成することができるということを理解しておかなければならない。「if,caseで型を含めて等しいかを判定して分岐」するか、または、「あらかじめ用意した連想配列(辞書)のキーとして存在するかをチェック」するという方法が最強と思われる。現実的な方法お使いのフレームワークが用意しているバリデーション機構を利用してください。その正規表現、大丈夫?一つの正規表現で無理やり入力値のバリデーションを実現することは避けた方が良い。ReDoS対策の観点から、できるだけシンプルな造りになるように処理をステップごとに分割し、一つ一つのコードを単純化することを検討しよう。メールアドレスのバリデーションを自前の一行正規表現で済ませてしまうのはやめよう。まって、その正規表現、本当に本当に大丈夫?入力文字列の長さを調べたいのならば、例えばPHPであればstrlenで判定できる。以下の処理をシーケンシャルに実行して、条件に反していたらその時点でリジェクトすればオッケーだと思うよ。「クラックされやすいパスワードリストに載っていないかを判定」しつこくてごめんね。その正規表現、本当にほんと~~に大丈夫?正規言語の限界、イプシロン遷移、バックトラック、DFAとNFAについて考えたことがない、「そんな単語聞いたことも無い」という状態であれば、頑張って複雑な一行の正規表現で済ませてしまうのは絶対にやめよう。「0回以上繰り返し」の量指定子は地雷です。*と{0,N}が該当しますね。https://twitter.com/adokoy0001/status/824580874704293889バックトラックが何なのか分かっていないのであれば、「極力正規表現を使わない方法」を模索しましょう。判定、などなど、有限オートマトンであるところの正規表現ではスタックがないので不可能です。いうのはプッシュダウンオートマトンであるところの文脈自由言語とかならできます。正規表現を積極的に使うべきシーンは、文字列の置換やパターンマッチした部分を抽出する処理などでしょう。それでも正規表現を使いたい場合どうしても入力バリデーションを正規表現一発でやりたいのであれば、以下のURLにある正規表現のやばい挙動を完全に理解した上でやりましょう。https://regex101.com/r/GM8BLm/2/debugger最後の量指定子{1,3}を、{1,50}にしてみよう。https://regex101.com/r/GM8BLm/3/debuggerおわかりいただけただろうか。50から70とかに増やすとタイムアウトになったりする。ここで重要なのは以下である。数字を増やすと指数関数的にステップ数が増える短い入力でもバックトラック地獄は起こりうる短くシンプルな正規表現でも危ないものは危ない量指定子*を使わなくても、イプシロン遷移があれば危ないこの投稿が何かのお役に立てれば幸いである。YokodaTweet。