web-dev-qa-db-ja.com

PHPでセッションを管理する正しい方法は?

現在、認証システムをセットアップしています。現在のレイアウトでは、$_POST、md5のパスワードから彼のメールを取得し、データベースを彼のメールとパスワードと照合します。一致する場合は、session_startを使用して、次のように$_SESSION変数にデータを格納し始めます。

 $_SESSION['uid'] = $uid;
 $_SESSION['first_name'] = $first_name;

そして、ウェブサイトのすべてのページで、私は簡単なチェックを行います

isset($_SESSION['uid']);

そうでない場合は、インデックスページにリダイレクトし、ある場合はページをロードします。

私はこれを正しく行っていますか?これで十分ですか?誰かがそのデータを偽造するのはどれほど簡単ですか?

ユーザーのメールとセッションIDを使用してテーブルを作成し、それを使用して管理する必要があると誰かが私に言った...

誰かがこれを明確にできますか? PHPセッションで認証を管理する正しい方法は何ですか?

ありがとう。

38
daniel

セキュリティアップデート:2017-10-23現在:この回答のアドバイスは、歴史的に重要ではありますが、完全に安全ではありません。 md5は簡単にブルートフォースされるため、パスワードのハッシュにmd5を使用しないでください。組み込みのpassword_ * apiを使用してパスワードをハッシュおよび検証する方法については、 この回答 を参照してください。


私は以前にログイン/認証システムを扱ってきましたが、この方法にはいくつかの欠点があります。

  • あなたは「彼のパスワードをmd5し、データベースをチェックします」-これは、ある人がデータベースにアクセスできる場合、同じパスワードを持っている人を知ることができることを意味します!

ADDENDUM(2015年9月19日)*これを見てください link 。それはすべての基本、取ることのできるアプローチ、それらのアプローチを取るべき理由、そしてサンプルのPHPコードを説明します。それが長すぎる場合は、最後に移動して、コードを取得して設定してください!

BETTER APPROACHusername+password+email+saltのmd5をデータベースに格納します。saltはランダムです。ユーザーの記録と一緒に保存されます。

  • セッション変数で「uid」を直接使用すると、非常に危険な場合があります。これを考慮してください。私の友人は私のブラウザからログオンしており、彼はリークのために出発します。私は彼のブラウザにどのCookieが設定されているかをすぐに確認し、彼の「uid」を解読しました。今私は彼を所有しています!

BETTER APPROACH:ユーザーが正常にログインしたときにランダムなセッションIDを生成し、そのセッションIDを$_SESSION[]配列に格納します。また、(データベースまたはmemcachedを使用して)セッションIDを彼のuidに関連付ける必要があります。利点は次のとおりです。

  1. セッションIDを特定のIPにバインドして、セッションIDがキャプチャされても悪用されないようにすることもできます。
  2. ユーザーが別の場所からログオンした場合、古いセッションIDを無効にすることができます。したがって、私の友人が自分のコンピュータからログインすると、私のコンピュータのセッションIDは自動的に無効になります。

編集:私は常にセッションを処理するために手動でcookieを使用してきました。これにより、WebアプリのJavaScriptコンポーネントをより簡単に統合できます。今後、アプリでも同じものが必要になる可能性があります。

43
jrharshath

これを行うことには何の問題もありません

isset($_SESSION['uid']);

セッションデータはユーザーに送信されず、サーバー(またはセッションハンドラーがデータを保存する場所)に保存されます。ユーザーに送信されるのは、PHPによって生成されたランダムな文字列であるセッションIDです。これは、ユーザーに送信されるため、もちろん盗まれる可能性があります。

データベースとユーザーセッションに文字列をランダムに保存し、それを使用してユーザーを識別することは、攻撃者がセッションを取得してもユーザーを危険にさらす可能性がある場合、セッションの安全性を高めることにはならないことに注意してください。

私たちが今話し合っているのは セッションハイジャック です。IPアドレスをセッションに保存し、リクエストからのIPでそれをチェックしてそれを実行できると考えているかもしれません。しかし、それほど単純ではないことがよくあります。最近、大規模なWebアプリケーションでセッションにユーザーエージェント+ IPアドレスのハッシュを保存し、99%のユーザーについてそれらが一致することを確認していたときに、これはうまくいきました。しかし、説明なしでログアウトされ続けていると感じていた人から電話がかかってきました。何が起こっているのかを確認するためにセッションハイジャックチェックにログを記録し、これらの人々が1つのIPにアクセスし、セッションが別のIPで継続することを発見しました。これはハイジャックの試みではありませんでしたが、プロキシサーバーの方法に関するものでした。結果として、セッションハイジャックコードを修正して IPアドレスのクラス を確認し、そこからIPアドレスのネットワーク部分を特定して、IPアドレスのこれらの部分のみを保存します。これはそのセッションでの安全性はやや劣りますが、理論的には同じネットワーク内からハイジャックされる可能性がありますが、すべての誤検知はなくなりました。

26
linead

これに追加する必要があります。 「MD5パスワード、次にデータベースをチェックする」方法を実行している場合、これはパスワードが単一のmd5ハッシュに格納されていることを示唆しています。これはハッシュされたパスワードを保存する標準的な方法ではなくなりました。

このリンクは非常に有益であることがわかりました: http://www.itnewb.com/tutorial/Encrypting-Passwords-with-PHP-for-Storage-Using-the-RSA-PBKDF2-Standard

4