デスクトップアプリケーションからデータベースセキュリティをどのように処理しますか?


12

約10年間、私はSQL Serverデータストアを使用して社内のさまざまなデスクトップクライアントアプリケーションに取り組んできました。これらのプロジェクトを開始したことはほとんどありませんでした。ほとんどは買収作業です。

どこでも一定のように思われることの1つは、このアプリケーションが使用する単一のグローバルSQL Serverユーザーアカウントがあり、それが共通データベースへのアクセス許可を付与しsaたことです。 。

アプリケーションがデータベースへのアクセスに使用するこのユーザー名とパスワードを実際に非表示にすることはできません。通常、ファイルに保存されているiniconfig、実行可能ファイル自体に焼き付けられています。いずれの場合も、少し掘り下げればユーザーに表示されます。あるケースでは、実際にconfigファイルを使用して暗号化しましたが、もちろん暗号化キーを実行可能ファイルに保存する必要がありました(この制限にナイーブではありませんでしたが、十分に精通している人をいじるのを効果的に阻止しました)configファイルを検索します)。

これらのシステムはすべて、アプリケーションに組み込まれたユーザー認証システムを備えていましたが、もちろん、すべてアプリケーション自体で管理されていました。つまり、ユーザー情報はデータベースに保存されていました。アプリケーションは、アクセスレベルに基づいて実行できることを制限していましたが、データベースに接続してアドホッククエリを実行できる場合は、あらゆる意味で意味がありません。

この問題を回避するために他のシステムが何をするかを知りたいです。私が知っているオプションは次のとおりです。

  1. SQL Serverのセキュリティメカニズムを使用してユーザーとロールのリストを管理し、デスクトップアプリケーションにT-SQLクエリを介してユーザーを追加および削除させます。
  2. データベースに直接接続する代わりに、サーバー上で実行される何らかの種類のWebサービスを作成し、そこに認証ロジックを配置します。すべてのリクエストにセキュリティ検証を実行させます。

ユーザーをデータベースから分離しているため、ユーザーは最上級のエンティティではなく、外部キー関係などでそれらを参照できないため、最初のオプションは少しいです。

2番目は、大きなパフォーマンスの問題のように思えますが、多くの余分な作業があり、さらに、NHibernateのようなORMマッパーを簡単に使用することはできません(と思います)。

誰でもこれを経験していますか?ベストプラクティス?

編集

もう少し考えて、SQL Server認証は実際にこの問題を解決できますか?たとえば、タイムシートを編集できるようにユーザーがタイムシートレコードを挿入および更新できる必要がある場合、SQLサーバーがタイムシートの詳細テーブルの他の行へのアクセスを禁止する方法はありません。つまり、他の人のタイムシートも読み書きできます。


バインディングのトピック。NHibernateのようにORMを使用しないことは(私が思うに)非問題です。Webサービスを例として使用すると、データをXMLに効率的にバインドする多くの方法が見つかります。
ジェイソン

とにかく、ビジネスオブジェクトとDBエンティティ間の直接マッピングとしてORMを使用するべきではありません。これは、脆弱なインターフェイスを作成する貧弱なアプローチです。生のDBエンティティを取得し、必要なデータのみをクライアントに返すビジネスレイヤーに要求を行います。
gbjbaanb

@gbjbaanb-確かに、今日の午後にアーキテクチャ全体を変更します。:)
スコットホイットロック

誰かがあなたをハッキングするまで待ってから変更することができると思いますが、明るい面では、少なくとも上司に再設計のための資金を提供しても問題はありません:
gbjbaanb

レコードを更新する唯一の方法としてストアドプロシージャを使用し、クエリの一部としてprocを実行しているユーザーを使用することにより、ユーザーが他の誰かのレコードを更新できないようにすることができます。CURRENT_USER
gbjbaanb

回答:


9

Webサービスレイヤーを追加することが、おそらくあなたの問題の正しい解決策だと思います。

クライアントを基礎となるデータベース実装から分離することは、おそらく長期的にも役立つでしょう。

Webサービスレイヤーを追加しても、必ずしもパフォーマンスを損なう必要はありません...

実際、適切なAPIを使用すると、Webサービスは、WANを介した複数の往復を必要とせずに、データセンターLAN内で複数のデータベースクエリをバッチ処理することで、実際にパフォーマンスを改善できます。

そしてもちろん、Webサービスレイヤーはしばしば水平方向にスケーリングでき、データベースクエリに適切なキャッシュを追加できます。おそらく変更通知メカニズムですらあります。

サーバーレイヤーは、リモートクライアントで実行されているアプリでは保証できないセキュリティを追加します。クライアント上で実行されるものはすべて「ハッキング」される可能性があり、実際には何らかの方法で信頼されると見なされるべきではありません。クライアントにプレゼンテーションロジックを実際に配置し、完全に制御できるハードウェア上で重要なものをホストする必要があります。

私はあなたのアプリについては知りませんが、私のWebアプリは自然にいくつかのレイヤーに分割され、プレゼンテーションコードは少なくとも2つのビジネスロジックのレベルによって永続化レイヤーから分離され、2つを分離しています。これにより、アプリの推論がはるかに簡単になり、機能の追加または変更が非常に速くなります。とにかくレイヤーが分離されている場合、プレゼンテーションレイヤーをクライアントに保持し、残りを自分の管理下にあるサーバーに保持するのは比較的簡単です。

そのため、「Webサービス」レイヤーを導入せずに問題を解決できますが、標準のデータベースセキュリティ実装の穴を埋めるために必要なすべてのストアドプロシージャ(または同等のもの)を作成するまでに、おそらく適切な単体テストを作成できるサーバー側アプリケーション。


パフォーマンスのボトルネックである必要はありませんが、確かにアーキテクチャに余分なレイヤーが追加されるため、より多くのメンテナンスが必要になります。
スコットホイットロック

3
レイヤーが追加されますが、メンテナンスは必ずしも必要ではありません。クライアントではなくサービスにすべてのロジックを配置すると、ユーザーがクライアントアプリケーションを更新しなくても、変更を「ロールアウト」できることを考慮してください。
GrandmasterB

5

jmorenoの答えと同様に、ストアドプロシージャのEXECUTE権限以外のすべてへのユーザーアクセスを拒否し、所有権の連鎖を利用して、ストアドプロシージャがテーブルで必要な操作を実行できるようにします。

詳細については、https://msdn.microsoft.com/en-us/library/bb669058(v = vs.110).aspxを参照してください

ユーザーがユーザー名/パスワードのクライアント側を入力すると、それらを保存し、すべてのストアドプロシージャコールにパラメーターとして送信します。その後、目的の操作を実行する前に、テーブルに保存されている値に対してそれらを検証できます。

セキュリティの最後の言葉ではありませんが、PCに汎用ログインがあり、ADグループを使用して権限を制限したり、AD自体へのアクセスが制限されている場合に必要になることがあります。


2

1つのアプローチは、ADグループとストアドプロシージャを使用して、ユーザーができることを制限することです-たとえば、タイムシートDBは、ユーザーの時間の挿入、更新、削除を許可しますが、他の人の時間の更新は許可しません。ユーザーのIDはDBエンジンによって提供され、ユーザーはログインIDに基づいてクエリを実行したspのみにDBテーブルに直接アクセスできません。

もちろん、これは常に実現可能ではありませんが、実現可能です。最適なアプローチは、要件とリソースに依存します。


これは私が考慮していなかったものです。ぴったりかどうかはわかりませんが、うまくいくでしょう。
スコットホイットロック

1

「Webサービス」としてあなたが示唆するものはn層アーキテクチャと呼ばれます。一般に、セキュリティまたは構成の問題が発生する可能性がある場合(たとえば、多くのオフィスにアプリケーションを配布する場合)の方法です。ただし、「Webベース」である必要はありません。多くは他のプロトコルで動作します。

クライアントとデータベース(およびその他のリソース)の間の仲介として機能するアプリケーションサーバーを作成します。アプリケーションサーバーは、アプリケーションベースの認証を処理し、クライアントに代わってアクションを実行します。実際、理想的には、クライアントでSQLを実行するのではなく、アプリサーバーでメソッドを呼び出します。アプリケーションサーバーはすべてのデータ操作を処理します。

このアプローチには多くの利点があります。クライアントでデータベース接続とドライバーを構成する必要はありません。データベースユーザー、パスワード、およびサーバーを保存しないでください。クライアントの構成は必要ありません。正しいURLまたはアドレスをコードでポイントするだけです。また、アプリケーションサーバーの「ロジック」を使用すると、他のアプリケーションを開発するときに同じことを繰り返す必要はありません。同じアプリケーションサーバーを異なるタイプのクライアントで再利用できます。


さらに良いことに、誰かが(またはWebベースの同等のWebサーバーで)デスクトップをハッキングした場合、攻撃者はOSに完全にアクセスできますが、DBにはアクセスできません。そのため、彼らは「select * from users」をファイルにパイプして実行し、暇なときにクラックして、安全なシステムが侵害された理由をCEOにメディアに説明することはできません。あなたもアクセスのみを実行できますDB上のストアドプロシージャを使用している場合、攻撃者は、あまりにもアプリのサーバをハックすることができ、彼らはまだあなたの全体のユーザーデータベースを取得することはできません。
gbjbaanb

1

テクノロジーは少し変わりました。データベース自体に対して各ユーザーを認証し、データベースロールを使用する場合、少なくともSQL Serverでは、更新可能なビューと呼ばれるものを使用してこの問題を解決できるようになりました。

更新可能なビューは、テーブルSomeTable内の各行が従業員にリンクされているというテーブルに対してどのように見えるかを示しています。従業員は自分にリンクされた行を表示できる必要があり、HRロールのメンバーはすべての行を表示できる必要があります。たとえば:

CREATE VIEW [dbo].[vwSomeTable]
AS
    SELECT SomeTable.*
    FROM SomeTable
        INNER JOIN Employee ON SomeTable.Employee_ID = Employee.Employee_ID
    WHERE Employee.Username = USER_NAME() OR IS_MEMBER('HR_Role')=1

GO

そして、何をやっていることはギブ読み(そしておそらく書き込み)である権限ビュー上のvwSomeTable)すべてのユーザーに、とに何の権限与えないテーブルをSomeTable)。

これは次のようにテストできます。

EXECUTE AS USER = 'Some_Regular_Username'
SELECT * FROM vwSomeTable

...これらの行のみを返す必要があります。または:

EXECUTE AS USER = 'Some_HR_Username'
SELECT * FROM vwSomeTable

...すべての行を返します。このテストを実行するには、実行者(偽装)権限が必要であることに注意してください。

ビューは更新可能であるため、行が自分のEmployee行にリンクされている限り、通常のユーザーでもこれを行うことができます。

UPDATE vwSomeTable
SET SomeColumn = 5
WHERE SomeTable_ID = 'TheID'

0

証明書ベースの認証を使用することは、共有SQLアカウントを実装する「正しい」方法です。目標は、この種のことのためのパスワードの使用を排除することです。

更新:

質問を誤解したと思います。アプリケーションの構成にdbユーザー名とパスワードを入力するか、アプリケーション自体にバックアップする代わりの方法を見つけることに関係していると思いました。

代わりにクライアント側の証明書を使用することにより、アプリケーションでパスワードを管理する問題を解消できます。証明書自体では十分ではありません。証明書の取り消しなどの操作が可能な配布および管理システムが必要です。

参照:http : //en.wikipedia.org/wiki/Public-key_infrastructure


これについてさらに情報を提供できますか?それは私の元の質問の意図に直交しているように聞こえますが、興味深いです。
スコットホイットロック

0

新しいデスクトップセキュリティソリューションを構築するために、以下で説明するWebサービスソリューションを選択しました。

開発者とは別の環境でデスクトップアプリケーションの実行可能ファイルをコンパイルします。そして、データベースに記録されている実行可能ファイルからHASHを計算します。

アプリケーションの実行に必要なすべての情報、DBパスワード、接続文字列情報、ユーザー権限などを提供する1つのWebサービス

アプリケーションごとにシングルDBログインを使用し、セッション変数にデータベースのユーザー詳細を記録して、レコードを監査できるようにします。

DLLは、デスクトップアプリケーションからWebサービスへのすべての通信を処理します。これは、DLLに組み込まれたトークンでのみアクセス可能です。

WebサービスからアプリケーションDBパスワードを取得できるように、DLLはランタイムでDLL呼び出し元のHASHを計算し、DLLトークンと実行時ランタイムのHASHを検証したWebサービスにパラメーターとして渡します。 (アプリケーションは、単一のネットワーク共有インストールでのみ使用可能です)。

そのようにして、私たちは、いくつかの設計上の欠陥に最も関心があり、よく知っているセキュリティ問題に対する良い解決策になりました。この実装はほぼ終了しており、これまでのところ、結果に満足しています。

編集:デジタル署名とX.509証明書を使用して、ハッシュアイデアを置き換えることができます。


1
明白なセキュリティホールがどこにあるかは、かなり明らかなようです。話すDLLはクライアントのシステム上にあり、サーバーコードがDLLの正当なコピーまたはハッキング/悪意のある/偽のコピーと通信していることを確認する方法はありません。セキュリティを追加することなく、多くの作業を自分用に作成しました。悪意のある人が必要とするのは、トークンとアルゴリズムだけです。どちらも、見たい人のためのDLLにあります。
スコットホイットロック14

@ScottWhitlock、はい、同意します。DLLとHTTPSを経由するトラフィックの難読化を検討しています。私たちはそれを改善しようとしています。それを改善する方法についてのご意見をお待ちしています。しかし、このソリューションは、ネットワークファイルに保存されているプレーンテキストパスワードなど、現在のシステムが抱えている多くの問題をすでに解決しています。また、このWebサービスでは、ここで使用しているクライアント言語(DelphiクライアントやClipper(Harbor)クライアントなど)がアクセスできる多くのコードを再利用できます。
ビトーアーベックス14

システムでは、ユーザーはログインし、おそらくWebサービスによって認証されます。HTTPSの使用を想定すると、それだけでは十分ではありませんか?ユーザーが自分の言うとおりの人物であることがわかっているため、クライアントソフトウェアを信頼する必要はありません。また、Webサービスを制御します。クライアントをリバースエンジニアリングし、独自に作成したとしても、どのような損害を与える可能性がありますか?WebサービスのみがDBパスワードを知っているため、安全である必要があります。
スコットホイットロック14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.