コールスタックのどこでロールチェックを行う必要がありますか?
-
20-08-2019 - |
質問
私の典型的なアプリでは、ユーザーは aspx ページのボタンをクリックし、C# ビジネス オブジェクトを呼び出し、ストアド プロシージャを実行します。
ロールチェックはスタックの最上位、最下位、またはすべてのレベルで実行する必要がありますか?悪意のあるユーザーが 1 つのメソッドを呼び出すことができる場合、任意のメソッドを呼び出すことができるようです。そのため、効果的なセキュリティを実現するには、すべてのメソッドをチェックする必要があります (そして、それを記述するには大量の追加コードが必要になります)。
私の質問を説明するための典型的なコールスタックは次のとおりです。
Page_Load()
{
if(p.IsInRole("Managers")) //or equivalent attribute
{
AddAccount.Visible =true;
}
}
AddAccount_OnClick()
{
if(p.IsInRole("Managers")) //or equivalent attribute
{
//Add the account
Account.Add(...); //and maybe another role check...
}
}
-- TSQL doesn't understand .NET authorization, this call is in a 'trusted' subsystem
create proc Add_Account @user, @account_name
If @user in (Select user from role_table where role='manager')
-- Add the account
解決
私の意見では、あなたは、可能な限りデータの近くにそれを置く必要があります。近いあなたがデータに、より良いあなたはアクセスチェックを回避するためにあなたのコードベースをいくつか遠回りのルートを取ることは不可能であることを確認することができます。
という議論は、それは(あなたの好きなRDBMSのように)それをサポートしている場合、データソース自体のいずれかに配置されているセキュリティチェックのために呼び出す、またはデータアクセス層です。
ただし、いくつかのセキュリティ上の制約は、ビジネス・ロジックの強い臭気を持っています。例えば「ユーザーは、この役割であり、これらの仕様を満たすデータを変更しようとする場合、操作は許可されなければならない、そうでない場合ではありません」。それは政策のように私に聞こえる、と種類の別々のルールエンジンのビジネスロジック層のいずれかに属して何かます。
他のヒント
実装の観点から、可能な限りスタックダウンチェックを実施するための最良の解決策になります保護層を通過しなければなりません。あなたの基盤が保護されている場合は、その基盤の上に構築するすべてのものを気にする必要はありません。
このソリューションは、1つのobviouseの欠点を持っている - ユーザーインターフェイスは、認証、認可、データ検証、および他のすべてのものについて何も知りません。だから、すべての入力には、エラーが発生する可能性があり、スタックをダウンして、ユーザーに通知するために再びスタックを上がります。簡単にユーザーインターフェイスで検出することができたのエラーが唯一のバックエンドシステムにデータを渡した後に検出されているので、これは不愉快なユーザーエクスペリエンスの原因となります。その結果では、優れたユーザー体験を提供するためには、あまりにも、ユーザーインターフェースに多くのチェックを追加します。
あなたはインターフェイスベースのプログラミングを使用する場合は、アプリケーション層の間に確認コードを共有することができますので、、これは、全く問題ありません。 1つのアプリケーション層でのバグは別の層で捕捉することができます - これは、あなたは簡単にすべてのアプリケーションレイヤに確認コードを追加すると、これは深さであなたの防御を与えるさらに可能になります。検証コード自体が誤っているとあなたが共有している場合はもちろん、それはアプリケーション層、バグをaccross、おそらくすべてのアプリケーション層を介しprobagateますエラーをHANCEます。
私は実際には潜在的に危険/敏感なものを実行し、ビジネス・オブジェクト内の役割のアクセスチェックを置きます。
あなたのページの負荷やボタンのクリックイベントに役割のチェックを追加すると、私見無関係のだろう。あなたがページを保護しようとしている場合に加えて、例えば...あなたのweb.configファイルで、宣言の場所ディレクティブを使用してページを保護宣言、別のフォルダに「管理者」ページのすべてを入れて、フォルダ全体を保護します。
しかし、あなたは常に最低でも、あなたのビジネスオブジェクトのメソッドのチェックを持っている必要があります。
あなたは、メソッドレベルでそれを配置する必要があります。あなたが任意の特定の方法でそのメソッドに到達することを仮定することはできません。その方法は、ボタン・ハンドラによって呼び出されることができ、またはそれは論理の任意のタイプの結果として、通常のコードで呼び出すことができます。何回あなたが
...]ボタンハンドラを呼び出すこのようなものを見てきましたprivate void MyBypassingCall()
{
if( myLogic )
{
AddAccount_OnClick();
}
}
だから、Page_Loadの上に置くだけでは十分ではありません。また、 PrincipalPermissionAttribute <持つメソッドを飾るチェックアウトする必要があります/>。それは、多くのコードが削減ます。
これは、ビジネス側でセキュリティ検証を行うことがいかに重要であるかを示す、単なる逸話的なコメントです。私たちの場合、リクエストのハッキングの可能性が低いと楽観視するのは十分ではありませんでした。私たちはビジネスオブジェクトにいかなる検証も行わなかったため、予期せぬ形で炎上してしまいました。クライアントは、サイトの使用を自動化するスクリプトを作成しました。最終的には、実際にはレンダリングされなかったスクリプト内の予期されたリンクをたどることになりました。結局データが壊れてしまいました。もちろん、これはセキュリティ侵害というよりも、システムの状態とデータの整合性の問題です。しかし、実際には両方が当てはまると思います。
ビジネスオブジェクトます。
しかし、建設時。各インスタンスは非常に特定の役割をキャプチャしてみましょう。
編集:より簡潔この方法