PHPセッションIDの一意性


90

PHPセッションIDはどのくらい一意ですか?私が読んださまざまなことから、2人のユーザーが同じセッションIDを取得することに決して依存してはならないという印象を受けました。GUIDではありませんか?

回答:


39

Session_idは実際に重複する可能性がありますが、確率は非常に低いです。あなたが公正なトラフィックのあるウェブサイトを持っている場合、それはあなたのウェブサイトの生活の中で一度起こるかもしれません、そしてただ一つのセッションのために一人のユーザーを困らせるでしょう。

非常に高トラフィックのWebサイトや銀行業界向けのサービスを構築することを期待しているのでない限り、これは気にする価値がありません。


4
衝突が多発したサイトの報告を聞いています。
ColinM

20
質問はほぼ4年前に行われました。それ以降、セッションIDアルゴリズムが即興であるかどうかを知るのは興味深いことです...
Sliq

@ColinM:これらのサイトには、1日あたり100万人のユニークユーザーがいます。
e-satis

1
それとは別に、ユーザーのリモートアドレス、現地時間、およびいくつかの乱数(LCG)に現在基づいています(MD5 / SHA1ハッシュ
カラミエル2013

2
モバイルを壊す必要はありません。モバイルは常に壊れます。:)
hakre 14

67

出荷されているため、それほど独特ではありません。デフォルトの構成では、gettimeofdayの結果(ひどく一意ではない)を含むさまざまなもののハッシュの結果ですが、心配な場合は、/ dev / urandomからエントロピーを描画するように構成する必要があります。

ini_set("session.entropy_file", "/dev/urandom");
ini_set("session.entropy_length", "512");

コードで「php_session_create_id」を検索して、使用している実際のアルゴリズムを探します。

追加用に編集:pidによってシードされたDFA乱数ジェネレーターがあり、usecsの時間と混合されています。これは、特にセキュリティの観点から見た場合一意の一意性条件ではありません。上記のエントロピー設定を使用します。

更新:

PHP 5.4.0以降、session.entropy_fileのデフォルトは/ dev / urandomまたは/ dev / arandomです(使用可能な場合)。PHP 5.3.0では、このディレクティブはデフォルトで空のままです。PHPマニュアル


1
ええ、私が敵の戦闘員などに対して超安全でなければならないウェブサイトの契約だったとき、私は実際に自分のセッションハンドラーを作成し、random.orgから直接エントロピーデータを供給しました。しかし、そのシステムのREQSはるか;-)最も単なる人間はワット/を扱うものを超えていた
セオドアR.スミス

1
@ thomas-jensen、gettimeofday UNIXタイムスタンプですが、μsec(時々)で表されます。上記のphp_session_create_idメソッドを読んでください。
djsadinoff

4
エントロピーの長さを変更すると、ランダムさが改善されますが、ハッシュは同じ長さであるため、衝突の可能性に大きな影響はありません。ただし、session.hash_functionを変更すると、たとえばsha512のような長いハッシュを使用できます。
ColinM

2
衝突があるのは奇妙です。確かにPHPが...そこに有効なセッションがそのIDの下にあり、その後、別のIDを生成するかどうかを確認するためになされるべきである
ルーク

1
@ theodore-r-smith、公開されているソースからエントロピーを取得することは本当に悪い習慣です。「敵の戦闘員」もrandom.orgにアクセスできると想定する必要があります...
avri

12

PHPがデフォルトでセッションIDを生成する方法を知りたい場合は、Githubのソースコードを確認してください。これは確かにランダムではなく、これらの成分のハッシュ(デフォルト:md5)に基づいています(コードスニペットの310行目を参照)。

  1. クライアントのIPアドレス
  2. 現在の時刻
  3. PHP線形合同ジェネレーター -擬似乱数ジェネレーター(PRNG)
  4. OS固有のランダムソース -OSに使用可能なランダムソースがある場合(/ dev / urandomなど)

OSに使用可能なランダムソースがある場合、セッションIDを目的として生成されたIDの強度は高くなります(/ dev / urandomおよび他のOSランダムソースは、(通常)暗号的に安全なPRNGです)。しかし、そうでない場合は問題ありません。

セッションID生成の目標は次のとおりです。

  1. 同じ値の2つのセッションIDが生成される可能性を最小限に抑える
  2. ランダムなキーを生成し、使用中のキーをヒットすることは、計算上非常に困難になります

これは、セッション生成に対するPHPのアプローチによって実現されます。

一意性を完全に保証することはできませんが、同じハッシュを2回ヒットする確率は非常に低いため、一般的に言って、心配する価値はありません。


11

IDの生成方法をカスタマイズする場合は、代替のハッシュ生成関数をインストールできます(デフォルトでは、MD5を介して生成される128ビットの数値です)。http://www.php.net/manual/en/session.configuration.php#ini.session.hash-functionを参照してください

PHPセッションの詳細については、この優れた記事http://shiflett.org/articles/the-truth-about-sessionsを試してください。セッションの固定とハイジャックに関する他の記事にもリンクしています。


2
正確には、PHP 5.3以降で「session.hash_function = sha512」を設定して、512ビットハッシュに設定します。これでうまくいくはずです。デフォルトでは、トラフィックの多いサイトでは衝突が発生するのが一般的です。
ColinM

5

session_idのサイズ
seesion_idは均一に分散され、size = 128ビットであると想定します。地球上のすべての人が1日に1回ログインし、新しいセッションが1000年間持続するとします。

num_sesion_ids  = 1000*365.25 *7*10**9 < 2**36
collission_prob < 1 - (1-1/2**82)**(2**36)   1 - e**-(1/2**46) 
                 1/2**46 

したがって、1回以上の衝突の確率は70千億分の1未満です。したがって、128ビットのサイズのsession_idで十分です。他のコメントで述べたように、session_managerは、新しいsession_idがまだ存在していないことも確認する場合があります。

ランダム性
したがって、私が考える大きな問題は、session_id:sが適切な疑似ランダム性で生成されるかどうかです。その点については確信が持てませんが、この目的のために、よく知られており、頻繁に使用される標準ソリューションを使用することをお勧めします(おそらく既に使用しています)。

チェックによって衝突が回避されたとしても、乱雑性とsession_idのサイズは重要です。そのため、ハッカーは、どういうわけか修飾された推測を行い、大きな確率でアクティブなsession_id:sを見つけることができません。


3
私は数学者ではありませんが、誕生日の問題を忘れていると思うので、小さいうちに衝突する可能性は、あなたが提案するよりもはるかに大きくなります。また、djsadinoffが示唆したように、PHPはデフォルトで乱数を生成する優れた方法を必ずしも使用していません。
ColinM

実際には見積もりはありません。上記の計算は簡略化された推定値であり、session_id nr iの衝突の確率は= 1/2 82と推定されます(= typoの上の1/2 92 である必要があります)。実際には、以前の衝突が発生していない限り、確率は(i-1)/ 2 128です。1/2 92は最後のsession_idに対してのみ保持されます。
MrJ、2012

3

私はこれの確認を見つけていませんが、phpがそのIDでセッションIDを作成する前に、そのセッションIDがすでに存在するかどうかを確認すると思います。

人々が心配しているセッション乗っ取りの問題は、誰かがアクティブなユーザーのセッションIDを見つけたときです。これは多くの方法で防ぐことができます。詳細については、php.netのこのページセッション固定に関するこのペーパーを参照してください。


2
...しかし、あなたがいくつかの銀行の1つのphpサーバーである場合、サーバーがsesssionIDがまだ使用されているかどうかを知るのに十分な知識を持っている保証はありません。
djsadinoff 2008

2つの異なるphpサーバーで同じセッションIDを取得することが重要なのはなぜですか?2つの異なるドメインを想定すると、セッションCookieは各ドメインからのみアクセスできます...?
daremon 2008

3
マルチサーバー環境で重複を防止する最も簡単な方法は、memcachedセッションハンドラーを介してセッションをmemcachedに保存することです。問題が解決され、ユーザーは、データを失うことなく、diffサーバーをバウンスできます。
セオドアR.スミス

@daremon彼は1つのドメインの複数のサーバーについて話している。
gtd

これは単に正しくありません。PHPは、新しいセッションIDを生成するときに既存のセッションIDをチェックしません。PHPセッションハンドラコードを見てください。この目的のために実装されているメソッドはありません。
ColinM

2

いいえ、セッションIDはGUIDではありませんが、2人のユーザーはサーバー側に格納されているため、同じセッションIDを取得しないでください。


2
おそらく、サーバー側のストレージが一意性を保証しないためです。一意性は1つです。衝突が発生すると、セッションが格納されている場所に関係なく衝突します。

私ではなく、あなたの(そして他の)回答に感謝します。-Jalov
Jalov

2
セッションIDはサーバー側とクライアント側の両方に保存されます。セッションの内容はサーバー側に保存されます。そして、事実はセッションIDの一意性とはほとんど関係ありません。
YudhiWidyatama 2013年

-3
<?php
session_start();
$_SESSION['username']="username";
?>

<!DOCTYPE html>
<html>
<head>
    <title>Update</title>
</head>
<body>

<table border="2">
    <tr>
        <th>Username</th>
        <th>Email</th>
        <th>Edit</th>
    </tr>
<?php
     $conn=mysqli_connect("localhost","root","","telephasic");
     $q2="select * from register where username = '".$_SESSION['username']."'";
     $run=mysqli_query($conn, $q2);
     while($row=mysqli_fetch_array($run))
     {
         $name=$row[1];
         $email=$row[2];
     ?>

    <tr>
        <td><?php echo $name; ?></td>
        <td><?php echo $email; ?></td>
        <td><a href="edit.php"> Edit </a></td>
    </tr>
 <?php } ?>
 </table> 
 </body>

ユーザー名が異なる場合や一意の場合は、このコードをセッションに使用できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.