データのセキュリティはデータベース側で実行する必要がありますか?

StackOverflow https://stackoverflow.com/questions/55845

  •  09-06-2019
  •  | 
  •  

質問

私たちは、新しい社内アプリのための新しいフレームワークとビジネスのやり方を確立しているところです。現在の設計では、すべてのセキュリティ ロジックをデータベースで処理する必要があり、すべての情報 (つまりすべて) がストアド プロシージャを介してデータベースに出入りすることになります。

理論的には、データ アクセス層はストアド プロシージャから情報を要求し、認証をデータベースに渡します。データベースはユーザーの役割/権限を決定し、タスク (データの取得または更新のいずれか) を実行するかどうかを決定します。

これはデータベーストランザクションが少なくなることを意味すると思います。データベースへの 1 回の呼び出し。セキュリティがデータ アクセス層にある場合、ユーザーに適切なアクセス許可があるかどうかを判断するために 1 回のデータベース呼び出しが必要になり、その後、アクションを実行するために 1 回の別のデータベース呼び出しが必要になります。

私自身、SQL Management Studio は IDE としては完全に不足していると感じています。私の主な懸念は、最小限のパフォーマンス向上のために、ストアド プロシージャ内で厄介な量のビジネス ロジックを維持しなければならなくなることです。

現在、ORM に LINQ を使用しています。軽くて速いように見えますが、何よりも迅速に開発するのが非常に簡単です。

メンテナンスコストはパフォーマンスの向上に見合う価値がありますか?私たちはパフォーマンスが顕著に向上するだろうと思い込んでいるのでしょうか?それとも自分自身が悪夢を作っているだけなのでしょうか?

私たちの環境:

  • 社内の非ミッションクリティカルなビジネス アプリ
  • C#/ASP.NET 3.5
  • Windows 2003
  • MS SQL サーバー 2005
  • 約 500 ユーザーがいる中規模の Web アプリ 35 個
役に立ちましたか?

解決

そんなことはしないでください. 。最近、 ひどい 「データベースの第一人者」が別の会社に行くことを決めたときの経験。プロシージャ内のすべてのロジックのメンテナンスは、まったくひどいものです。

はい、パフォーマンスは多少向上しますが、それだけの価値はありません。実際、内部アプリケーションではパフォーマンスは大きな問題ではありません。優れたサーバーにもっとお金を投資しましょう。それは報われます。

他のヒント

残念ながら、「唯一の正解」はありません。選択する必要があるのは、次のような複数の要因によって決まります。

  • 与えられたソリューションに対するチームの精通度 (つまり、チームの大多数が SQL の作成に慣れている場合は、データベースに含めることができますが、チームの大多数が C# の方が慣れている場合は、コードに含める必要があります)
  • 各政党の「政治力」

どの方向にも決定的な利点はありません (パフォーマンスの向上は最小限であるとおっしゃいました)。心に留めておくべき 1 つのことは、DRY (Don't Reply Yourself) 原則です。機能を 2 回 (コード内と DB 内で) 再実装しないでください。同期を維持するのは悪夢のような作業になるためです。解決策を 1 つ選び、それを使い続けてください。

それを行うことはできますが、開発と維持は非常に面倒です。ほぼすべてのビジネス ロジックがストアド プロシージャでコーディングされているプロジェクトに携わっている人の話です。

セキュリティのために、ASP.NET にはユーザーとロールの管理が組み込まれているため、データベースへのアクセスを節約できるかもしれませんが、それではどうでしょうか?その代わりに、システム エラーや検証エラーはデータベースからバブルアップする必要があるため、それらの処理とデバッグがはるかに面倒になります。

単体テストの sproc に利用できるフレームワークがはるかに開発されていないため、単体テストははるかに困難です。

適切な oop およびドメイン駆動設計は、ほとんど不可能です。

また、パフォーマンスの向上はあったとしてもごくわずかです。私たちはこれについて話しました ここ.

開発者として正気を保ちたい場合は、データベースを永続層としてのみ維持するために必死に戦うことをお勧めします。

私見では:

アプリケーション サービス層 -> アプリケーション ロジックと検証
アプリケーション データ層 -> データ ロジックとセキュリティ
データベース -> データの一貫性

遅かれ早かれ、sproc アプローチにハマってしまうことになるでしょう。私はこれを苦労して学びました。
Proc は、多くのパフォーマンスを必要とするワンショット操作に最​​適ですが、CRUD 部分はデータ層の仕事です

通常、ストアド プロシージャはセキュリティにとって有利です。アプリケーションとデータベース間の関係を単純化すると、エラーが発生する可能性のある箇所が減ります。ビジネス ロジックをデータベースに接続するコード内のエラーは、セキュリティ上の問題となる傾向があります。したがって、ストアド プロシージャに物事をロックダウンすることについて DBA が間違っているわけではありません。

アプリケーションをストアド プロシージャにロックダウンすることのもう 1 つの利点は、アプリ スタックのデータベース接続の特権を特定のストアド プロシージャ呼び出しのみにロックダウンできることです。

アプリケーションのセキュリティ ロジックに DBA を関与させる利点は、さまざまなアプリの機能とロールをデータベース内でビューに分割できるため、動的 SQL と汎用 select ステートメントが必要な場合でも、SQL の脆弱性による被害を軽減できることです。制約することができる。

もちろん、その反面、柔軟性が失われます。ORM は、ストアド プロシージャのパラメータに関して DBA と定期的にネゴシエーションを行うよりも明らかに開発が速くなります。そして、これらのストアド プロシージャに対する圧力が高まるにつれて、プロシージャ自体が動的 SQL に依存する可能性がますます高まっており、アプリで構成された SQL と同じくらい攻撃に対して脆弱になります。

ここには幸せな中間点があるので、それを見つけるように努めるべきです。最近私が取り組んだプロジェクトは、かなりひどい SQL インジェクションの問題から救われました。その理由は、DBA がデータベース、接続、ストアド プロシージャを「最小限の権限」で慎重に構成し、データベース ユーザーが自分の権限でアクセスできるものにのみアクセスできるようにしていたからです。知る必要がある。

アプリのロジックで SQL コードを記述するときは、パラメーター化されたプリペアド ステートメントを一貫して使用していること、入力をサニタイズしていること、国際化された入力に注意していることを確認してください (単一の SQL コードを記述する方法はたくさんあります)。 -quote over HTTP)、入力が列幅に対して大きすぎる場合のデータベースの動作に注意する必要があります。

すべてはケースに応じて異なりますが、おそらく SP ルートに行かず、すべてを DDD 方法で実行する方がよいでしょう (コードでドメイン モデルを作成し、それを使用します)。

ただし、自分のアプリケーションだけでなく多くの人が使用するデータベースがある場合は、おそらく Web サービスを検討する必要があります。いずれにしても、データベースにはビジネス ルールを適用する 1 つのレイヤー経由でのみアクセスできるようにする必要があります。そうしないと、「汚い」データが作成されることになり、後でデータをサニタイズすることは、事前にいくつかのビジネス ルールを記述するよりもはるかに面倒です。優れたデータベースにはチェック制約とインデックスが設定されている必要があり、好むと好まざるにかかわらず、いくつかのビジネス ルールが存在します。

そして、何百万、何十億ものレコードを扱わなければならない場合、問題を解決してくれる優秀な DB 担当者がいれば、喜んでいることでしょう。

私の意見は、アプリケーション自体が認証と認可を処理する必要があるということです。データベース側では、必要な場合にのみデータの暗号化を処理する必要があります。

私は過去にストアド プロシージャ ベースのアプリケーションを構築したことがあります。あなたの場合、データベース層で認証を維持し、ビジネスロジックをC#で持つ方法があるかもしれません。ビューを使用してデータを制限します (権限のある行のみが表示されます)。これらのビューは、テーブルと同じように簡単に LINQ で使用できます。ストアド プロシージャを使用して更新が行われるように設定します。

これにより、linq、C# のビジネス ロジック、およびデータへのアクセスを制御するデータベース内の共通認証層が可能になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top