2008-08-02 12 views
125

PHPで責任あるセッションセキュリティを維持するためのガイドラインは何ですか?ウェブ上に情報があり、すべての情報が1か所に集まってきました。PHPセッションセキュリティ

答えて

88

観光名所のカップルは、セキュアなセッションを維持するためにあります。

  1. 使用SSLは、ユーザーの認証や機密操作を実行する場合。
  2. セキュリティレベルが変更されるたび(ログインなど)にセッションIDを再生成します。必要に応じて、リクエストごとにセッションIDを再生成することもできます。
  3. セッションタイムアウトを持ってグローバルにサーバー上の
  4. ストアの認証の詳細を登録し、使用しないでください。つまり、クッキーにユーザー名などの詳細を送信しないでください。
  5. $_SERVER['HTTP_USER_AGENT']を確認してください。これにより、セッションハイジャックに対する小さな障壁が加わります。 IPアドレスを確認することもできます。しかし、これは、複数のインターネット接続などで負荷分散するためにIPアドレスを変更するユーザーには問題を引き起こします(ここの環境ではそうです)。
  6. あなたはセッションデータがあることを確認する必要が再び
+15

一部の操作でのみSSLを使用するだけでは、暗号化されたトラフィックと暗号化されていないトラフィックに対して別々のセッションがない限り、十分ではありません。 HTTPSとHTTPでシングルセッションを使用する場合、攻撃者は最初のHTTPS以外の要求で盗みます。 – Kornel

+0

私はporneLに同意します。 また、6番の場合、攻撃者があなたのセッションIDを持っていれば、ユーザエージェントにもアクセスできませんか? – Chad

+0

セッションIDを再生成すると、攻撃者がHTTPS以外の要求を盗み出すセッションIDは役に立たなくなります。 – grom

15

1つのガイドラインは、セッションのセキュリティレベルが変更されるたびにを呼び出すことです。これにより、セッションのハイジャックを防ぐことができます。

11

(PHP 6で扱っている)大きな問題の一つは、register_globalsだと思います。現在、register_globalsを回避するために使用される標準的な方法の1つは、$_REQUEST,$_GETまたは$_POSTの配列を使用することです。

"正しい"方法(5.2のように少しバグはありますが、すぐに来る6の時点で安定しています)はfiltersです。

ので、代わりの:

$username = $_POST["username"]; 

あなたはどうなる:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING); 

あるいは単に:

$username = filter_input(INPUT_POST, 'username'); 
+2

これは全く問題とは関係ありません。 –

+5

本当ですか?それでは、なぜ受け入れられた答えでレジスタ・グローバルを使用しないことに言及していますか?ほとんどの常用の開発者が関わっている限り、 "セッション"オブジェクトの一部ではないにしても、グローバルを登録し、変数処理を "セッション"の傘の下に置くのではないでしょうか? – cmcculloh

+0

-1これは質問に答えません。 – Tomas

3

これは非常に簡単かつ明白ですが、後にsession_destroyに確認してくださいあらゆる用途。これは、ユーザーが明示的にログアウトしないと実装が難しいため、タイマーを設定してこれを行うことができます。

ここでは、setTimer()とclearTimer()ではtutorialが良いです。

3

PHPセッションとセキュリティ(セッションハイジャックのほかに)の主な問題は、あなたがどのような環境にあるのかです。デフォルトでは、PHPはセッションデータをOSの一時ディレクトリのファイルに保存します。特別な考えや計画がなければ、これは世界が読めるディレクトリなので、すべてのセッション情報はサーバーにアクセスできるユーザーには公開されます。

複数のサーバーでセッションを維持するためのものです。その時点で、セッションデータをCRUD(作成、読み取り、更新、削除)するために提供された関数を呼び出すユーザ処理セッションにPHPを切り替えるほうがよいでしょう。その時点で、すべてのアプリケーションサーバーがデータにアクセスできるように、セッション情報をデータベースまたはソリューションのようなmemcacheに格納できます。

あなた自身のセッションを保存することは、あなたがしばしばファイルシステムをより制御できるデータベースに保存することができるので、共有サーバーを使用している場合に有利かもしれません。

2

私は、彼らはIPアドレスを使用して

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT'] 
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR']) 
{ 
    //Something fishy is going on here? 
} 
+5

ユーザーが負荷分散されたプロキシファームの背後にある場合、IPは正当に変更できます。 – Kornel

+2

user_agentは、ユーザーがブラウザをアップグレードするたびに変更できます。 – scotts

+3

@scotts私はIP部分に同意しますが、ブラウザのアップグレードではログイン時にセッションを設定するので、再度ログインすると新しいセッションを作成せずにブラウザをアップグレードする方法はわかりません。 – JasonDavis

5

を変更するかどうかを確認するためにIPとユーザーエージェントの両方をチェックします私の経験で本当に最高のアイデアではありません。例えば;私のオフィスには負荷に応じて使用される2つのIPアドレスがあり、私たちは常にIPアドレスを使用して問題にぶつかります。

代わりに、私は自分のサーバー上のドメイン用の別のデータベースにセッションを格納することを選択しました。この方法では、ファイルシステム上の誰もそのセッション情報にアクセスできません。これは3.0以前のphpBBには本当に役立っていました(彼らはこれを修正しています)が、私はまだ良いアイデアだと思います。

2

session_set_save_handler()を使用する場合は、独自のセッションハンドラを設定できます。たとえば、セッションをデータベースに格納することができます。 PHPを参照してください。データベースセッションハンドラの例のネットコメント。

複数のサーバーがある場合はDBセッションも有効です。そうでない場合はファイルベースのセッションを使用している場合、各Webサーバーがセッションを読み書きするために同じファイルシステムにアクセスする必要があります。

2

を自分authenicationの詳細を提供するために、ユーザーがログインしている必要検討したファイルシステム上のセッションへのアクセスをロックダウンや機密操作について

  • を取り扱うカスタムセッションを使用安全。あなたのphp.iniを見たり、phpinfo()を使ってセッション設定を見つけることができます。 _session.save_path_は、それらが保存されている場所を示します。

    フォルダとその親の許可を確認してください。パブリック(/ tmp)にしたり、共有サーバー上の他のWebサイトからアクセスできないようにしてください。

    php sessionを使いたいと仮定して、_session.save_path_を変更して別のフォルダを使用するように設定するか、_session.save_handler_を変更してデータベースにデータを保存することができます。 php_value session.save_path "/home/example.com/html/session"

    あなたはあなたのサイトのルートフォルダに.htaccessファイルに、またはApache + mod_phpのために(一部のプロバイダがそれを許可する)あなたのphp.iniで_session.save_path_設定することができるかもしれません。 _session_save_path()_で実行時に設定することもできます。

    Chris Shiflett's tutorialまたはZend_Session_SaveHandler_DbTableをチェックして、代替セッションハンドラを設定してください。

  • 11

    私の2つ(またはそれ以上)のセント:

    • 信託誰
    • フィルタ入力を、出力エスケープ(クッキーを、セッションデータがあまりにもあなたの入力されている)
    • も形成され、あなたのHTMLを保つ(XSSを避けてください、
    • Defense in depth
    • は、データ
    を公開しないでください) PHPTALまたは HTMLPurifierを見てみましょう

    Essential PHP Security by Chris Shiflettという小さなトピックですが、このトピックに関する本があります。ブックのホームページで

    Essential PHP Security http://shiflett.org/images/essential-php-security-small.png

    あなたは、いくつかの興味深いコード例とサンプルの章があります。

    あなたは(IP &のUserAgent)上記の技術を使用することができますが、ここで説明:How to avoid identity theft

    +0

    +1 for XSS-prevention。それがなければ、CSRFから保護することは不可能であり、誰かがセッションIDを取得しなくてもセッションに乗ることができます。 – Kornel

    3

    を私はページ内のログにthis-

    ように私のセッションを設定します。

    $_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']); 
    

    (設定ページで定義されているフレーズ)

    次に、残りのサイトのヘッダ:

    session_start(); 
    if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {  
        session_destroy(); 
        header('Location: http://website login page/'); 
        exit();  
    } 
    
    3

    php.iniの

    session.cookie_httponly = 1 
    change session name from default PHPSESSID 
    

    EQ Apacheのヘッダを追加します。

    X-XSS-Protection 1 
    
    +0

    あなたは精緻化できますか? – domino

    +0

    httpd.conf - >ヘッダセットX-XSS-Protection "1" user956584

    +0

    'X-XSS-Protection'は本当に役に立った。実際には、保護アルゴリズム自体が実際に悪用される可能性があり、以前よりも悪化しています。 – Pacerier