web-dev-qa-db-ja.com

APIで公開されるIDの増分を回避するにはどうすればよいですか?

StackOverflowで this などの投稿を見ると、セキュリティのために、増分するIDを外部APIから非表示にする必要があるというコンセンサスがあるようです。

ただし、適切な実装を作成するのに問題があります。

here のように、ページの断片化につながり、以前にそれを行ったときに、DBにパフォーマンスの問題があったため(一部はIDが原因で)、GuidsをIDとして使用したくありません。

次のクラス構造を思いつきました。 int IDがあり、外部識別用にGuidがあります。これに関する問題は、挿入と更新のためにdbへの過剰な呼び出しがあることを意味することです。

モデル:

public class Blog
{
    public int BlogId { get; set; }
    public Guid BlogGuid { get; set; } = Guid.NewGuid();
    public string Url { get; set; }
    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public Guid PostGuid { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

DTO:

public class BlogDto
{
    // No int id on dto
    public string Url { get; set; }
    public Guid BlogGuid { get; set; }
    public List<PostDto> Posts { get; set; }
}

public class PostDto
{
    // No int id on dto
    public Guid PostGuid { get; set; }  
    public string Title { get; set; }
    public string Content { get; set; }

    public BlogDto Blog { get; set; }
}

データの取得は問題ありません。前と同じように、取得してDTOに変換します。

更新または挿入を行う場合、データはすべてのオブジェクトのGUID IDだけで返されます。 this などのチュートリアルのように、エンティティを送り返すことはできません。

次に、元のデータ(Guid、インクルード付き)を取得する必要があります。次に、関連データ(Guidによって)を取得し、何をすべきか(挿入、削除、または変更された可能性がある)を調べる必要があります。それはすべて少し厄介で、データベースと不必要に雑談しているように感じます。

これはより安全=遅い場合に過ぎませんか、それともこの設計(私が思っているように)がなんらかの非効率的ですか?

5
HockeyJ

クラスター化された主キーにGUIDを使用することについての リンクした投稿 でのアドバイスは7歳で、今日はほぼ間違いなく悪いアドバイスです。 参照する記事 参照SQL Server 7。

データベース内のすべての主キーにGUIDを使用し、JSONサービスにアクセスするURLにそれらのGUIDを公開します。これは、データベースの内部を外部に公開しないためです。この情報がない場合は、乱数を公開することもできます。その投稿で予測されているパフォーマンスの問題はありません。

GUIDには、主キーおよび外部キーとして非常に役立つ固有のプロパティがあります。 グローバルに一意であるため、結合するテーブルを気にすることなく、単一のJOINを使用できます。連続したIDとは異なり、隣接するGUID=を推測することは、GUIDを理想的な識別子にする最初の理由と同じ理由で、ほとんど不可能です。

増分IDの公開を防ぐ理想的な方法は? 代わりにGUIDを主キーとして使用します。GUIDは魔法のセキュリティ機能ではありませんが、どちらもintを難読化しません。残りのセキュリティ(SSL、ログイン、ロールベースのセキュリティ、Xサイトリクエストフォージェリからの強化など)が最初に堅実であることを確認し、GUIDを公開してそれらが何であるかを示しますとにかく表現するように設計されている(つまり、固有のリソース)は、問題が最も少なくなります。

18
Robert Harvey

StackOverflowでこのような投稿を見ると、セキュリティを確保するために、増分するIDを外部APIから非表示にする必要があるというコンセンサスがあるようです。

セキュリティについて話すときはいつでも、最初の質問は「私はどの脅威から保護しているのですか?」リンクする質問で概説されている脅威を見てみましょう。

  1. 順次IDを使用すると、攻撃者は自分のどこかに属していないIDを入力できます。データに適切な権限がない場合、許可されていないデータにアクセスできます。
  2. SQLインジェクション攻撃でデータを見つけやすくします。
  3. サイトの使用量に関する情報を公開する場合があります。
  4. 彼らは、セッションIDを推測し(シーケンシャルの場合)、他の誰かのセッションを引き継ぐことができます。

要約すると、中心的なテーマは、攻撃者がシステムにどのようなIDがあるかをある程度知っている可能性があるということです。しかし、この情報はほとんどそれ自体では役に立たない。 IDは、攻撃者がそのIDを使用できるようにする別の脆弱性と組み合わせる必要があります。具体的には

  1. IDを介した不正アクセスを可能にする脆弱性が必要です。
  2. SQLインジェクションの脆弱性が必要です。
  3. これは広く当てはまりますが、気にしますか?
  4. セッションの乗っ取りを防ぐには検証の欠如が必要です。 (これには通常、何らかの暗号化手法が含まれるため、実際には順次IDをここで破棄する必要があります。ただし、プレーンテキストGUIDは、攻撃者が取得すると、同様に脆弱になります。)

サイトの使用状況の統計は別として、これらすべては単にIDを漏洩するよりもはるかに危険な脆弱性です。システムにこれらの他のギャップのあるセキュリティホールがないことを確認することは、使用するIDの種類を心配するよりもmuchより高い優先順位である必要があり、それらを接続すると、IDは役に立たない情報になります。

ここで、GUIDを使用してもここでは役に立たないことについて少し考えてみましょう。攻撃者は、GUIDを使用してIDにもアクセスできる可能性があります

  1. ソーシャルエンジニアリング:多くの場合、ユーザーはセキュリティの最も弱いリンクです。
  2. SQLインジェクション:アプリがSQLインジェクションに対して脆弱である場合、攻撃者がこの脆弱性を利用してIDを取得できる可能性が非常に高くなります。 (これは、脆弱性をどのように導入したかに関する正確な詳細に依存しますが、それは間違いなくあなたが心配すべき可能性です。)
  3. 盗まれたデータベースダンプ:攻撃者がサーバーに違反し、DBの完全なコピーを入手した場合、すべてのID(およびすべてのパスワードまたはトークンデータとDB内の他の情報)。

GUIDは問題ありませんが、セキュリティが主な目的ではないため、一瞬、GUIDを盲目的に使用することがセキュリティ対策であると考えるべきではありません。それらはbestのあいまいさによるセキュリティの形式にあり、情報がプライベートに保持される必要がある場合、あいまいさはシステムが依存すべきものではありません。 IDの有用性を高める脆弱性の回避に焦点を当てます。

GUIDは、特に2つの異なる場所にデータを保存して後で結合する必要がある場合に、グローバルに一意のIDとして主に役立ちます。これが必要なければ、GUIDがなくても問題ないでしょう。 StackOverflowは、ユーザー、投稿、またはその他の何にも結局それらを使用しないため、自動的に脆弱性にさらされることはありません。それらを使用してサイトの使用量を隠す必要がある場合、それは合理的です。ただし、その情報を秘密に保つことはビジネス要件であり、アプリケーションの要件を設定する人と一緒に評価する必要があります。GUIDの使用はおそらくとにかくその問題を解決するための唯一のコンポーネント。 「より安全である」という漠然とした概念からではなく、アプリケーションの要件に基づいてGUIDを使用するかどうかを決定する必要があります。

11
jpmc26
  1. 先に進み、GUIDを使用してください
  2. クラスタ化インデックスを使用しないでください。
  3. クラスター化インデックスを使用する必要がある場合は、新しいNEWSEQUENTIALID()を使用してそれらを生成します。

GUIDの使用に対するアドバイスには日付が付けられているというロバートハーベイの声明に同意しません。クラスタ化インデックスでGUIDを使用する必要がある場合は、NewsequentialID()を使用することを推奨する クラスタ化インデックスのGUIDについて話しているより最近の投稿SQL Server 2012のドキュメントを含む があります。そのアドバイスは今日でも関連があります。

0
Moby Disk