1

内部的には、私の Web サイトは、整数の主キーによってインデックス付けされたデータベースにユーザーを保存します。

ただし、ユーザーを、さまざまな状況でそれぞれ使用される、推測が困難な一意の識別子に関連付けたいと思います。例:

  • ユーザー プロファイル URL 用の 1 つ: したがって、実際の主キーを含まない URL によってユーザーを見つけて表示できるため、プロファイルがスクレイピングされるのを防ぐことができます。
  • 1 つはログインなしのメール配信停止フォームです。ユーザーはログインせずにメール内のリンクをクリックしてメール設定を変更できるため、他の人が URL を簡単に推測してメール設定を改ざんすることを防止できます。

私が見ているように、これらの識別子に必要な重要な特性は、それらが簡単に推測されないこと、一意であること、およびキーまたは識別子を知っていても他の識別子を簡単に見つけることができないことです。

それを踏まえて、私はSecureRandom::urlsafe_base64を使用して、新しいユーザーが作成されるたびに、目的ごとに 1 つずつ、複数のランダム識別子を生成することを考えていました。それらはランダムであるため、一意性を保証するために、挿入前にデータベース チェックを行う必要があります。

誰でもサニティチェックを提供し、これが合理的なアプローチであることを確認できますか?

4

2 に答える 2

3

あなたが使用している方法は安全な乱数発生器を使用しているため、そのうちの 1 つを知っていても次の URL を推測するのは困難です。ランダム シーケンスを生成する場合、これは心に留めておくべき重要な側面です。安全でないランダム ジェネレーターは予測可能になる可能性があり、1 つの値を持つことで、次の値がどうなるかを予測するのに役立ちます。あなたはおそらくこれで大丈夫です。

また、urlsafe_base64そのドキュメントでは、デフォルトのランダム長は 16 バイトであると述べています。これにより、8 16の異なる値 (2.81474977 × 10 14 ) が得られます。これは膨大な数ではありません。たとえば、1 秒あたり 10.000 のリクエストを行うスクレイパーは、約 900 年ですべての可能な識別子を試すことができることを意味します。今のところ問題ないように思えますが、コンピュータはますます高速になってきており、アプリケーションの規模によっては、これが将来問題になる可能性があります。ただし、最初のパラメーターを大きくするだけで、この問題を解決できます。

最後に、絶対に考慮すべきこと: データベースが漏洩する可能性。識別子が防弾であっても、データベースはそうではない可能性があり、攻撃者はすべての識別子のリストを取得できる可能性があります。データベース内の識別子は、安全なハッシュ アルゴリズムを使用して確実にハッシュする必要があります (パスワードの場合と同じように、適切なソルトを使用します)。これがいかに重要かを理解していただくために、最近の GPU では、SHA-1 は 1 秒あたり 350.000.000 試行の速度でブルート フォースされる可能性があります。SHA-1 を使用してハッシュされた 16 バイトのキー (使用している方法のデフォルト) は、約 9 日で推測されます。

要約すると、アルゴリズムは十分ですが、キーの長さを増やしてデータベースでハッシュします。

于 2012-07-04T16:00:09.093 に答える
2

生成された ID は他のデータに関連付けられないため、推測するのが非常に困難 (不可能) になります。一意性をすばやく検証してユーザーを見つけるには、DB でそれらをインデックス化する必要があります。

また、次のような一意性をチェックする一意の ID を返す関数を作成する必要があります。

def generate_id(field_name)
  found = false
  while not found
    rnd = SecureRandom.urlsafe_base64
    found = User.exists?(field_name: rnd)
  end
  rnd
end

最後のセキュリティ チェックです。変更を行う前に、識別子とユーザー情報との対応を確認してください。少なくとも電子メールは確認してください。

とはいえ、それは私にとって良いアプローチのようです。

于 2012-07-04T15:56:19.423 に答える