質問

  

編集:それ以来、 3141592 などのIDを vJST などの文字列に変換する効率的でエレガントなソリューションを見つけて公開しました。 PHPで利用可能です:

     

https://github.com/delight-im/PHP-IDs

     

背景を提供し、Knuthの乗算ハッシュを使用してからベース変換を実行して、一意で可逆の非シーケンシャルIDを生成します。

問題:

指定されたIDに従ってコンテンツが表示されるPHPに動的ページがあります。 idは常にGETパラメーターを介して送信されます。page.php?id = Xこれにより問題が発生します。サイト訪問者はidを列挙し、すべての異なるコンテンツページを簡単に確認できます。もちろん、これは不可能です。

これをどのように解決できますか

私のアプローチは、後でGETパラメーターとして使用されるリンクおよびフォームのすべてのIDをエンコードすることです。すべてのページの先頭で、指定されたIDが「本物」にデコードされます。データベースで使用されるID。これは良いアプローチですか?別の方法を選択しますか?

私のアプローチの可能な解決策:

整数idを基数38の整数に変換し、指定されたリストの文字で数字を置き換えます。エンコードされた文字列IDには次の文字を使用します。

a-z 0-9-_

他の文字も使用しますか?これらの文字の場合、私のスクリプトは次のようになります。

function id2secure($old_number) {
    $alphabet_en = array(0=>'1', 1=>'3', 2=>'5', 3=>'7', 4=>'9', 5=>'0', 6=>'2', 7=>'4', 8=>'6', 9=>'8', 10=>'a', 11=>'c', 12=>'e', 13=>'g', 14=>'i', 15=>'k', 16=>'m', 17=>'o', 18=>'q', 19=>'s', 20=>'u', 21=>'w', 22=>'y', 23=>'b', 24=>'d', 25=>'f', 26=>'h', 27=>'j', 28=>'l', 29=>'n', 30=>'p', 31=>'r', 32=>'t', 33=>'v', 34=>'x', 35=>'z', 36=>'-', 37=>'_');
    $new_number = '';
    while ($old_number > 0) {
        $rest = $old_number%38;
        if (!isset($alphabet_en[$rest])) { return FALSE; }
        $new_number .= $alphabet_en[$rest];
        $old_number = floor($old_number/38);
    }
    $new_number = strrev($new_number);
    return $new_number;
}

追加の質問:

私の関数の逆関数は何ですか?

あなたが私を助けてくれることを願っています。ありがとう!

役に立ちましたか?

解決

ユーザーはWebサイト経由でページにアクセスできますか?答えが「はい」の場合、これが本当に問題なのかどうかを自問する必要があります。

そうでない場合、問題はページを保護していないか、別の言い方をすれば、セキュリティの不明瞭さに頼っているということです。これは決して良い動きではありません。

私のアドバイス?適切なユーザーのみがページにアクセスできるようにページを保護するか、心配しないでください。

本当に心配する必要がある場合は、特定のページに適切な追加フィールドを渡すだけです。 IDからこれを構築しません。データベースにページエントリを作成するときに、おそらく別の番号またはGUIDを生成します。両方のフィールドが正しくない場合は、ページを表示しないでください。

単純な文字置換やその他の単純な難読化技術は忘れてください。時間の無駄です。

編集:同じ長さの連続していないIDを使用する場合は、自動インクリメントの主キーの代わりにUUIDの使用を検討してください。基本的に、これはアプリケーションレベルで実行されます。

  • 主キーをchar(36)に変更します。
  • insertステートメントで、キーを設定し、MySQL UUID()関数を設定する必要があります。

UUIDへUUIDであるかどうかおよびプライマリキーとしてのUUID 。これによりパフォーマンスが低下します(具体的には、ルックアップに整数ではなく文字を使用しているため)が、大きな(100万行以上)またはデータがない限り、おそらく実際には問題になりません。

他のヒント

Luhnなどのチェックサムアルゴリズムを使用

$id = 1337;

Luhnなどのチェックサムアルゴリズムを使用

$id = Luhn_Verify(

Luhnなどのチェックサムアルゴリズムを使用

$id = 1337;

Luhnなどのチェックサムアルゴリズムを使用

<*>

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits

Luhnなどのチェックサムアルゴリズムを使用

<*>

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id'] = Luhn_Verify(

Luhnなどのチェックサムアルゴリズムを使用

<*>

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id'], 3); // 1337, returns the original number of false if validation fails echo

Luhnなどのチェックサムアルゴリズムを使用

<*>

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id']; // 1337

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id'], 3); if ($id === false) { // someone is trying to guess the ID } else { // $id is valid, do the DB stuff here }

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits

Luhnなどのチェックサムアルゴリズムを使用

<*>

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id'] = Luhn_Verify(

Luhnなどのチェックサムアルゴリズムを使用

<*>

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id'], 3); // 1337, returns the original number of false if validation fails echo

Luhnなどのチェックサムアルゴリズムを使用

<*>

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>GET['id']; // 1337

編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:

<*>

パターンを推測することは難しくなりますが、それでもページを順番にウォークスルーすることは可能です。ルートパターンがシーケンシャルである限り、最終的に問題が発生します(実際のところ、それは実際には問題であり、あなたが気に入らないものではありません)。

IDに乱数を使用できます。これにより、ページIDとページ順序を簡単に推測できなくなります(これも重要な場合です)。

Hashids を使用してIDをエンコード/デコードすることもできます。

  

このコードは、作成されたIDをURLなどの表示可能な場所に配置する目的で作成されました。

  

Hashidsは、数字から短い一意の非連続IDを生成する小さなオープンソースライブラリです。
  347のような数字を&#8220; yr8&#8221;のような文字列に変換するか、[27、986]のような数字の配列を&#8220; 3kTMd&#8221;に変換します。
  これらのIDをデコードして戻すこともできます。これは、いくつかのパラメーターを1つにまとめたり、単に短いUIDとして使用したりするのに便利です。

この「問題」については気にしませんが、とにかく私のプロジェクトの1つでそのような方法を使用しました:

新しいページをDBに保存した後、 md5 of(record_id + page_title)を生成し、特別なフィールド pagecode に配置しました。次に、idではなく、そのページコードでページにアクセスしました。また、データベースの pagecode フィールドにインデックスを付けることをお勧めします。

  

サイト訪問者はIDを列挙できます   単にすべてを歩く   さまざまなコンテンツページ。この   もちろん、不可能であるべきです。

これがなぜ問題になるのかわからない-人々は site:domain.com を入力するだけでウェブサイト上のすべての(公開、Googlebotインデックス付き)ページのリストを見ることができるGoogle、そして彼らが望むならそれらをループします。使用する一意のインデックスを変更しても変更されません。

しかし、訪問者があなたのページに直接アクセスすることを本当に望まない場合、簡単な簡単な修正はGETの代わりにPOSTを使用することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top