データ入力検証-どこ?いくら?[閉まっている]


27

データ入力の検証は、常に私にとって非常に内部的な闘争でした。

レガシーアプリケーションリライトプロジェクトに実際のセキュリティフレームワークとコードを追加する寸前(これまでのところ、カードキャッスルに強力なレガシーセキュリティコードとデータ検証を保持している)、私はどのくらい検証すべきか、どこなど

プロのJava開発者としての5年間で、データ入力の検証とセキュリティ対策のための個人ルールを作成し、改良しました。私は自分の方法を改善したいので、皆さんからいくつかのアイデアを聞きたいと思います。一般的なルールと手順は問題ありませんが、Java固有のものも同様です。

要約すると、これらは私のガイドライン(3層のWebアプリケーションスタイルで公開)であり、簡単な説明があります。

  • 第1層のクライアント側(ブラウザ):最小限の検証、不変のルールのみ(必須の電子メールフィールド、1つのアイテムを選択する必要があるなど)。「6〜20文字」などの追加検証の使用頻度が少なくなります。これにより、変更のメンテナンス作業が増加します(ビジネスコードが安定したら追加できます)。

  • 第1層サーバー側(Web通信処理、「コントローラー」):このルールはありませんが、ここではデータ操作とアセンブリ/解析エラーのみを処理する必要があると考えています(誕生日フィールドは有効な日付ではありません)。ここにさらに検証を追加すると、簡単に本当に退屈なプロセスになります。

  • 第2層(ビジネス層):堅実な検証、それ以下。入力データ形式、範囲、値、メソッドをいつでも呼び出せない場合の内部状態チェック、ユーザーの役割/権限など。できるだけ少ないユーザー入力データを使用し、必要に応じてデータベースから再度取得します。取得したデータベースデータも入力と見なす場合、特定のデータが信頼できないか、DBで十分に破損していることがわかっている場合にのみ検証します。

  • 第3層(データ層/ DAL / DAO):データにアクセスするのはビジネス層のみであるため、ここでは多くの検証が必要とは考えられません(「param1がtrueの場合、param2はnullであってはならない」などの場合に検証します)。ただし、「ここ」を意味する場合、「データベースにアクセスするコード」または「SQL実行メソッド」を意味することに注意してください。データベース自体はまったく逆です。

  • データベース(データモデル):適切なプライマリキー、外部キー、制約、データ型/長さ/サイズを使用して、DB上の不正なデータや破損データを可能な限り回避するために、十分に考慮し、強力かつ自己強化する必要があります/ precisionなど-独自のプライベートディスカッションがあるため、このトリガーは除外します。

初期のデータ検証は優れており、パフォーマンス面でも優れていることは知っていますが、繰り返しデータ検証を行うのは退屈なプロセスであり、データ検証自体は非常に面倒です。これが、非常に多くのコーダーがそれをスキップするか、途中でやる理由です。また、常に同期されていない場合、重複する検証はすべてバグの可能性があります。これらは、時間、帯域幅、CPU、ケースバイケースで処理される例外を犠牲にして、ほとんどの検証をビジネス層まで許可することを好む主な理由です。

それで、あなたはこれについてどう思いますか?反対意見ですか?他の手順はありますか?そのようなトピックへの参照?寄付はすべて有効です。

注:物事のJavaの方法を考えている場合、私たちのアプリはSpring MVCとMyBatisを使用したSpringベースです(パフォーマンスと不良データベースモデルはORMソリューションを除外します)。Spring SecurityをセキュリティプロバイダーとJSR 303(Hibernate Validator?)として追加する予定です。

ありがとう!


編集:第3層に関する追加の明確化。


私のアドバイスは、Hibernate Validatorがどのように機能するかを調べることです。永続化中に検証が開始されるため、JSR 303が有用であるとは思いませんでしたが、基本的な検証に依存するビジネスルールがあったため、永続化のかなり前にいくつかのルールを適用する必要がありました。私の意見では、それは非常に閉じたモデルで機能します。間違って使っていたかもしれませんが、私の経験とは違う経験をした人はいませんでした。
ビネレイノルズ

@Vineet Reynolds Spring MVCでのフォーム検証に既に使用しました。本当に素晴らしい組み合わせです。細かいメッセージでサーバー側の検証を取得します。ほとんど労力なしで、適​​切なエラーがユーザーに表示されます。私はまだ利点を確信していないサーバー側オブジェクトで完全にテストしています。このサンプルポストをご覧ください。
2010/07

2
検証が多すぎるEveryWhereは、これらのユーザー入力@#!!@@!
チャニ

回答:


17

検証は一貫している必要があります。そのため、ユーザーが有効であると判断されたデータをWebフォームに入力した場合、クライアント側で実装しなかった基準のためにデータベース層によって拒否されるべきではありません。

ユーザーにとって、ページに大量のデータを入力することは、データベースへの重大なラウンドトリップの後、何かが間違っていることを通知するだけであるように見えるため、これ以上面倒なことはありません。これは、プロセスでクライアント検証をトリップした場合に特に当てはまります。

これらを公開するため、さまざまなレベルで検証を行う必要があり、潜在的に誰が呼び出しているかを制御できません。したがって、検証を1つの場所で定義し、必要な場所から呼び出されるように(可能な限り)調整する必要があります。これがどのように配置されるかは、言語とフレームワークによって異なります。Silverlightでは(たとえば)サーバー側で定義でき、適切な属性を使用してクライアント側にコピーされ、そこで使用されます。


2
+1絶対に。ASP.NET MVCについても同じことを言っていましたが、あなたは私にそれを打ち負かしました。:)本当に、システムが有効な状態にあることを確認するために、適切な検証のみが必要です。クライアント側のような検証の残りの部分は、ユーザーの使いやすさと時間の浪費を高めることです。そのため、これが主な焦点となります。一貫性が重要です。
ライアンヘイズ

2
「ラウンドトリップ」については、適切なエラーメッセージがページにリロードされ、すべてのフィールドに以前に入力したものが入力されていれば問題ありません(この最後の詳細ではほとんどのインターフェイスが不足しています)。エラーを返すのに時間がかかりすぎる場合は、追加のクライアント側検証の候補になります。
mdrg

そして、アプリ全体で検証を簡単に複製できる場合、それを無駄にする理由はありません。サーバー側では簡単ですが、クライアント側では、あなたが言及したような検証ツールがないと、非常にイライラします(つまり、サーバーで書いたようなJS検証コードをたくさん書く) 。
mdrg

9

リレーショナルシステムでは、3層のアプローチと考えています。各レイヤーは以下のものによって制約されます。

  • プレゼンテーション/ UI
    • 簡単な入力検証
    • 入力の形式が間違っている場合は先に進まないでください
    • クライアント要求をサーバーに「ゲート」して、往復を減らし、使いやすさと帯域幅/時間を削減します。
  • 論理
    • ビジネスロジックと認可
    • ユーザーに許可されていないことをさせない
    • ここで「派生」プロパティと状態を処理します(データベースで非正規化されるもの)
  • データ
    • 不可欠なデータ整合性レイヤー
    • ジャンク品の保管を絶対に拒否する
    • DB自体がデータ形式(int、dateなど)を実施します
    • データベースの制約を使用して適切な関係を確保する

これに対する理想的な答えは、1つの場所で3つのレイヤーすべてで制約を定義できるシステムです。これには、SQLのコード生成と、少なくともクライアントとサーバーのデータ駆動型検証が含まれます。

ここに特効薬があるかどうかはわかりませんが... JVMを使用しているので、少なくともクライアントとサーバー間でJavaScript検証コードを共有するためにRhinoを確認することをお勧めします。入力検証を2回記述しないでください。


Rhinoを見てみましょう。Spring MVCフォーム検証となんらかの方法で統合できる場合は、はるかに優れています。
mdrg

7

•第3層(データレイヤー/ DAL / DAO):ビジネスレイヤーのみがデータにアクセスするため、ここでは多くの検証が必要とは考えられません(「param1がtrueの場合、param2はnullであってはならない」など。

これはとても間違っています。検証を行う最も重要な場所は、データベース自体です。データはほとんどの場合、アプリケーション以外の影響を受けます(そうでないと思われる場合でも)。適切なコントロールをデータベースに入れないことは、せいぜい無責任です。これを行わないという決定により、他のどの要因よりもデータの整合性が失われます。データの整合性は、データベースを長期間使用するために重要です。優れたデータを含むデータベースレベルで整合性ルールを実施できなかったデータベースを見たことはありません(文字通り数千のデータベースにあるデータを見たことがあります)。

彼は私よりも良いと言っています:http : //softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress


この記事の最後の部分に同意しますが、この部分については明確にしていないと思います。質問の詳細を更新しました。ありがとう!
mdrg

2

上記のすべては、開発者とメンテナーが完璧であり、常に完璧に動作する完璧なコードを書くことを前提としています。将来のソフトウェアリリースでは、あなたが行ったすべての仮定を文書化し、文書化することはありません。また、ユーザーやハッカーが想像もしなかった方法でシステムにデータを入力します。

確かに、検証が多すぎるのは悪いことですが、プログラム、ネットワーク、OSが完璧であり、ハッカーがファイアウォールを通過できず、DBAがデータベースを手動で「微調整」しないとすると、おそらくさらに悪いでしょう。

物事の周囲に境界円を描き、それが保護している障害モードを特定し、その境界の適切なレベルのチェックを実装します。たとえば、データベースで無効なデータが表示されることはありませんが、どのように発生しますか?ユーザーは誰ですか、失敗のコストはいくらですか?

物理的な世界のセキュリティモデルを研究します。セキュリティは玉ねぎのように層状になっている必要があります。1つの厚い壁は、セキュリティが低いと見なされます。データ検証も同じ方法で検討する必要があります。


1

検証に関する2つの短い一般規則:

呼び出し元に返すことができる方法で無効な入力について通知する何か(エラー、例外)を返すことを保証しないものを呼び出す場合、それを検証します。

データを使用して他に何かを行う(意思決定、計算、保存など)場合は、検証します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.