顧客にフィードバック フォームを提供する Web ページを作成することを検討しています。
顧客が特定の注文に対して固有の URL を使用してこのフォームにアクセスできるようにしたいと考えています。簡単な例は、 http://www.example.com/feedback/012345の形式になります。
補足: 私はすでに URL の書き換えに精通しています。特定の言語または特定のサーバーでの URL の作成/リダイレクトは、この質問の範囲外です
顧客がフィードバック フォームにアクセスするために認証する必要がある (さらに言えば、アカウントを所有している) ことは容認できません。しかし、統計的正確性を懸念して、上記の example.com/feedback/[order_id] の明らかな解決策には満足できません。これにより、誰でも URL の ID を変更し、別の注文のフィードバックにアクセスできるようになります。
一方、レシートなどの印刷物からこれらの URL を入力できるようにしたいので、多くの「パスワードのリセット」リンクのように長いハッシュを提供することは有効なオプションではありません。
これに基づいて、次の基準があります。
- 注文ごとに一意の URL が存在する必要があります
- この URL は比較的人間が入力できるようにする必要があります。今のところ、これを「短い」と解釈してください。
- URL の文字を変更したり、他の順序にアクセスしたりすることはできません (妥当な確率の範囲内で)。
私の考えでは、URL に 2 つのデータを入れる必要があります。これに役立つ可能性がある顧客レコードには、人間が読み取れるデータがたくさんあります。たとえば、顧客ID、注文の連絡先電話番号、姓などです...これにより、1桁または2桁を変更する機能が削除されますが、表示されません退屈な攻撃者にとって、特定の URL の「推測可能性」が著しく向上します。
/feedback/[surname]/[id] の簡単な例を挙げると、単純な辞書攻撃でページを攻撃して有効な URL のセットを取得できます。
for x in range(00000,99999):
for name in ["jones","smith", ....]:
url = "http://www.example.com/feedback/"+name+"/"+x
if exists(url):
print(url)
次に考えたのは、tinyurl のようなサービスを念頭に置いて、ID 番号をハッシュ化し、/feedback/[hash]/[id] の形式で URL を提供することです
。おそらく、実際の数学的ハッシュではなく、自動インクリメント ID レコードを使用します。この方法はおそらく役に立たない
実際のハッシュ関数を使用する場合、ハッシュが明らかに ID 番号から派生していないことが重要です。/feedback/trpxq/53192 のような URL を提供しても意味がありません。それらの 1 つまたは 2 つを見た後、前のレコードを簡単に取得できるからです: /feedback/trpxp/53191
そのとき、ハッシュにソルトが含まれていれば、どのハッシュ関数が使用されたかを知っていても、古い有効な注文 ID をハッシュして有効な URL を表示することができないのではないかと考えていました。
最後に、実際の質問は次のとおりです。
7 ~ 10 桁の整数 ID と任意のソルトに基づいて、ハッシュの短い、自明ではない、比較的一意の英数字表現を作成するには、どの関数を使用するのが最適ですか?
これ自体は URL 短縮の問題ではないので、ハッシュ部分が ID 部分と同じ長さであれば問題ありません。10 文字までの英数字への削減は許容されます。
また、必ずしも URL にアクセスするたびにハッシュを計算する必要はありません。注文レコードが作成されたとき、またはその注文 ID でページが最初にアクセスされたときに計算できます。これは、ハッシュ関数が厳密に高速である必要がないことを意味します。
基本的にルックアップ目的でハッシュ テーブルを作成する可能性はありますが、この問題にはハッシュ テーブルと同じ制限はありません。ルックアップは既に一意の値に基づいて行われるため、競合解決が十分に行われている場合、厳密には必要ありません。特定のハッシュに対して同じハッシュを持つ別のレコードを見つけるのは困難です。
私たちは今、フィードバックフォームを保護するために何をする必要があるかという実際的な領域の外にいます.このデータは実際には保護するのにそれほど重要ではありません.セキュリティと読みやすさの両方を最大化する優れたソリューションがあるかどうかを知ってください。