質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.05%

phpでのセッション認証について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 6,579

score 73

前提

先日、以下の質問をさせていただきました。
phpでの認証について

その結果、phpでの認証に下記のページに書かれているセッション認証を使えば、
色々とうまくいくということが分かりました。
PHPによる簡単なログイン認証いろいろ

セッション認証について色々と調べましたが、腑に落ちない点や、
実装した際に不都合が生じる気がしています。

疑問に思ったこと

1. セッションIDについて

ログイン済みかどうかを下記のように判断していることが一般的なようです。

!isset($_SESSION['username']


ここで、クライアント側で適当なセッションIDを用いて
usernameが保存されているセッションをCOOKIE?に故意に作成することができれば、
usernameの値さえ変えれば、好きなユーザーとしてログインした状態を作れるような気がしています。
そこで、セッションIDを生成したタイミングで、そのセッションIDをサーバー側で保持し、
毎回usernameとセッションIDを照合することで乗っ取りは防げるのではと思いました。
ただ、そこで2番目の疑問が生じました。

2. 複数端末でのログインについて

google, facebookなど、複数端末でログインできるようなサービスはたくさんあります。
上記のように、usernameとセッションIDを照合する仕組みで実装した場合、
ログインごとにセッションIDが変更されてしまうため、
端末Aでログイン後、端末BでログインをするとセッションIDが変更され、
端末Aはログアウト状態になってしまうと考えました。
そこで、usernameとpasswordによる認証が成功したタイミングで、
usernameとサーバー側で保持している文字列を使ってハッシュ値を生成すれば、
複数端末で同じハッシュ値が生成され、認証を行うことができるような気がしています。
ただ、これではハッシュ値が固定値となってしまうため、セキュリティ的に問題がある気もしています。

上記を踏まえて

以上のことから、現状ではusernameとサーバー側で保持している文字列からハッシュ値を生成し、
それを認証で使う方法が最も効果的なのではと考えています。
これに対して、問題があればご指摘をいただきたいです。
また、上記の記述の中に間違っている認識があれば教えていただきたいです。
まだまだ勉強を始めたばかりで、説明部分で意味が通じていない箇所もあるかと思いますが、
ご意見いただけると幸いです。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+4

ここで、クライアント側で適当なセッションIDを用いて 
usernameが保存されているセッションをCOOKIE?に故意に作成することができれば、 
usernameの値さえ変えれば、好きなユーザーとしてログインした状態を作れるような気がしています。

いいえ,問題ありません.Cookieはクライアント側で管理されるデータで改変もやりたい放題できますが,セッションファイルはサーバ側で管理されており,中身がクライアント側に覗かれることはありません

問題は,どうやってPHPがセッションで個人を識別しているかということです.それに関してはこちらで順序立てて説明していますので,よかったらご覧ください.まとめると,

  • 新しい(PHPSESSIDをCookieとして送って来なかった)クライアントにはPHPSESSIDが発行される
  • 「このPHPSESSIDに対応するのはこのセッションファイル」というように管理される
  • $_SESSION['username']はセッションファイルに書かれている情報なので,クライアント側からは見えない

ということになります.クライアントが偽造できるのは$_COOKIE['PHPSESSID']のみですが,これを当てずっぽうに変更したところで「そんなセッションファイル無いよ」ということになって,空のセッションファイルが新規作成されるだけです.その場合$_SESSIONは空の配列になります.

PHPSESSIDベースで普通に実装すれば,複数端末からの同時ログインも何も悩むことなく取り扱えます.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/14 21:16

    qiitaの記事もmpyw様が書いた記事だったんですね。大変助かりました。ありがとうございました

    キャンセル

0

うーん、まずはご自身で仕様を確認し、試されるのがいいかと思いますよ。
参考URL

どのような値がセッションIDとしてcookieに保存されているのか、
HTTPリクエストヘッダとしてこれがどう送られるのか、
サーバ側でどのように$_SESSIONが扱われているのか。

この辺に想像や推測が混ざっていると、会話の前提が成り立ちません。
ブラウザ→サーバの値や挙動は
chromeなら開発者ツール
firefoxならfirebug
といったツールを使用することで詳細に確認できます。

簡単に回答すると

usernameが保存されているセッションをCOOKIE?に故意に作成することができれば、 
usernameの値さえ変えれば、好きなユーザーとしてログインした状態を作れるような気がしています。

ユーザIDとsessionIDには相関関係が存在しないこと、かつセッションIDは十分に長い文字列であるため、任意のユーザのセッションIDを狙って作ることは非常に困難だという前提に成り立っています。

これが覆されるケースとしては、
・cookieが何らかの理由で漏れた場合
・通信経路が暗号化されておらず、セッションIDが途中でキャプチャされた場合
・サーバ側でセッションIDが漏れた場合
・無限回の試行が可能な場合
です。
これらのケースの場合、クライアント側からのリクエストを信じるという仕組みである限り、
どんな方法でセッションIDを発行しても同じです。
そのため、

そこで、セッションIDを生成したタイミングで、そのセッションIDをサーバー側で保持し、 
毎回usernameとセッションIDを照合することで乗っ取りは防げるのではと思いました。 

をしたとしても、usernameも一緒に漏れることになるので意味がありません。

*これに対応しようとすると、
クライアント側が詐称した場合に通信が成り立たなくなるソースIPアドレス等を絡ませる、
SMSやメールを使って多段階認証をするなどのHTTP以外の方法で認証情報をやり取りする
といった方法が必要になってきます。

上記の理由から、
特に多重ログイン防止について何も考えずに作ると、
複数個所からのログインが出来るように出来上がります。

簡単なものでいいので、一度ログイン機能だけを持ったwebアプリケーションを作ってみることをお勧めします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.05%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る