GETパラメーターで自動インクリメントIDを非表示(PHP)
-
07-07-2019 - |
質問
編集:それ以来、
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万行以上)またはデータがない限り、おそらく実際には問題になりません。
他のヒント
$id = 1337;
$id = Luhn_Verify(
$id = 1337;
<*>
編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:
<*>GET['id'] = Luhn($id, 3); // 1337518, adds 3 checkdigits
<*>
編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:
<*>GET['id'] = Luhn_Verify(
<*>
編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:
<*>GET['id'], 3); // 1337, returns the original number of false if validation fails
echo
<*>
編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくても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
<*>
編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:
<*>GET['id'] = Luhn_Verify(
<*>
編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくてもIDが有効かどうかを確認できます。例:
<*>GET['id'], 3); // 1337, returns the original number of false if validation fails
echo
<*>
編集:言及するのを忘れましたが、このメソッドを使用すると、データベースにクエリを実行しなくても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を使用することです。