9

問題

Breeze に変更を保存するときに、サーバー側で実装する必要がある独自のセキュリティの量を正確に把握しようとしています。特に、悪意のあるユーザーが SaveChanges リクエストを手動でハッキングしたり、クライアントの JavaScript をハッキングしたりして、通常のビジネス ルールをバイパスする方法を考えています。たとえば、エンティティの外部キー ID を悪意を持って変更するなどです。

セキュリティの取り組みをどこに集中させる必要があるかを正確に理解したい。不要なセキュリティ層を実装するために時間を無駄にしたくありません。

サーバー側で .net および Entity Framework と共に Breeze を使用しています。

これは簡単な例です。ObjectAへの参照がありObjectBObjectA特定の によって所有されていUserます。したがって、私のデータベースは次のようになります。

ObjectA:

Id    ObjectB_Id    SomeField          User_Id
1     1             Alice's ObjectA    1
2     2             Bob's ObjectA      2

ObjectB:

Id    SomeOtherField
1     Foo
2     Bar

User:

Id    Name
1     Alice
2     Bob

このモデルから、私が持っているセキュリティ上の懸念は次のとおりです。

  1. 認証されていないユーザーにデータを変更させたくない
  2. Bob が Alice のObjectA
  3. アリスにObjectAボブのObjectB.
  4. User_Idボブが自分ObjectAをアリスに変えようとしてほしくありません。

(1) の解決策は自明です。SaveChanges メソッドに[Authorize]属性があることを確認します。

問題 2 から 4 を再現するために、Fiddler を使用して SaveChanges 要求を簡単に作成できます。たとえば、Aliceの ObjectA を Bob の を指すように変更する要求を作成できObjectBます。メッセージの内容は次のようになります。

"entities":
[
    {
        "Id":1,
        "ObjectB_Id":2,
        "SomeField":"Alice's ObjectA",
        "User_Id":1,
        "entityAspect":
        {
            "entityTypeName":"ObjectA:#MyNamespace",
            "defaultResourceName":"ObjectAs",
            "entityState":"Modified",
            "originalValuesMap":
            {
                "ObjectB_Id":"1"
            },
            "autoGeneratedKey":
            {
                "propertyName":"Id",
                "autoGeneratedKeyType":"Identity"
            }
        }
    }
],

予想通り、サーバー側にセキュリティが実装されていない場合、更新されObjectB_Idた値がデータベースに保持されます。

ObjectB_Idただし、 にのエントリがない場合、メッセージの本文で のoriginalValuesMap値を変更しても、データベースに更新されないことも確認しました。ObjectB_Id

一般的なルール?

したがって、これは、サーバーで従う必要がある一般的なセキュリティ規則が次のとおりであることを意味すると思います。

[2013 年 7 月 4 日に編集 - わかりやすくするために書き直しました]

一般に:

  • メッセージ内の何も信頼できません: originalValuesMap の値も、おそらく「変更されていない」値もありません。
    • 唯一の例外はエンティティの ID であり、これは正しいと想定できます。
    • おそらく「変更されていない」プロパティは、元のValuesMapになくても改ざんされている可能性があります

「変更されていない」プロパティ (originalValuesMap にもないプロパティ) の場合:

  • 「変更されていない」プロパティを「使用する」場合、メッセージの値を使用してはなりません。データベースからオブジェクトを取得し、その値を使用する必要があります。
    • たとえば、オブジェクトの所有権をチェックして、ユーザーがオブジェクトを変更できることを確認する場合、メッセージの UserId を信頼することはできません。データベースからエンティティを取得し、そこから UserId 値を使用する必要があります
  • まったく使用していないその他の「変更されていない」プロパティについては、改ざんされていても心配する必要はありません。

変更されたプロパティ (originalValuesMap にもあるプロパティ) の場合:

  • ビジネス ルールによって、特定のプロパティの変更が妨げられる場合があります。この場合、そのようなルールごとにチェックを実装する必要があります。

  • 値の変更が許可されていて、それが外部キーである場合は、セキュリティ チェックを実行して、新しい値がセッション ID で使用できることを確認する必要があります。

  • これらは改ざんされている可能性があるため、originalValuesMap の元の値は使用しないでください。

【編集終わり】

ルールの実装

これらのルールが正しいと仮定すると、変更された外部キーにセキュリティを実装するためのオプションがいくつかあると思います。

  • ビジネス ルールで特定のフィールドの変更が許可されていない場合は、SaveChanges リクエストを拒否します
  • ビジネス ルールで特定のフィールドの変更が許可されている場合は、新しい値が許可されていることを確認します。これを行う際に、originalValuesMap;は使用できません。データベース (またはセッション Cookie などの他の信頼できるソース) にアクセスする必要があります。

これらのルールを上で述べたセキュリティ上の問題に適用すると、

  • セキュリティ上の懸念 (2)。セッションのユーザー ID を、現在データベースにあるUser_IDと照合する必要があります。ObjectAこれは、リクエストに User_ID が含まれていなくても、その User_ID を信頼できないためですoriginalValuesMap

  • セキュリティ上の懸念 (3)。ビジネス ルールで の変更が許可されている場合、ObjectBの新しい値の所有者を確認する必要がありObjectB_Idます。これを行うには、指定された ObjectB をデータベースから取得します。これが の所有者でObjectBはない場合ObjectA、おそらく変更を拒否したいと思います。

  • セキュリティ上の懸念 (4)。ビジネス ルールで の変更が許可されている場合User、これは (2) で既にカバーされています。

質問

だから、本当に、私は正しい方向に沿って考えているという確認を探しています.

  1. 私の一般的なルールは正しいですか?
  2. ルールの実装は合理的に聞こえますか?
  3. 何か不足していますか?
  4. 私は物事を複雑にしすぎていますか?
4

2 に答える 2

0

私は同じ問題に関するガイダンスを探していましたが、あなたの素晴らしい分析を見つけてとてもうれしく思います. 私の意見では、私たちの問題に対する答えは異なります。ただし、数個以上のモジュールで構成され、1 年以上存続するアプリケーションについて話していると仮定するとです。

ルールが複雑になりすぎると、不適切なアプローチを使用している可能性があります。多くの優秀な開発者はこれらのルールに従って対処できると確信していますが、悲しいことに、私たちの仲間のほとんどは間違っているか、プレッシャーにさらされていることを忘れているでしょう。

Fowler、Evans、および Nilssons の出版物に戻って、大規模なアプリケーション (およびこれらには強力なセキュリティ要件がある) では、エンティティ モデルはクライアントにまったく公開されるべきものではないことを繰り返す必要があると思います。 (セキュリティ以外の理由でも - 保守性など)。

一方で、Greg Young と Udi Dahan によって後に提案されたこれらの元のアイデアの改訂を見る価値があります。これらは本質的に、読み取りのモデルは「データ」の書き込みのモデルと同じである必要はなく、多くの場合同じではないことを示しています。

これを要約すると、「実際の」モデルを照会せず、特別に構築されたモデルを使用する場合、基本ルールは、書き込みに Breeze を使用しないでください (DTO/プロジェクションを使用) 読み取りに使用する必要があると言えます。読み取り用 (例: テーブルではなくビュー)。

これらはすべて、ドメインとユースケースに従い、何よりもテスト駆動型アプローチに従っている場合に、非常に自然に現れます。テスト駆動開発に従っている間、ビジネス ルールの BeforeSaveEntities ソリューションで本当に終わるのでしょうか?

于 2013-12-16T21:52:50.640 に答える