17

これは、Web サイトで認証を制御するための私のコードです。私の論理が正しいかどうかはわかりません。ユーザー名とパスワードが正しい場合、次のことが起こります。

if(session_start())
{
        session_regenerate_id(true);//without this the session ID will always be the same
        $_SESSION['loggedInUser'] = $uName;
        echo 'You are now logged in';
}
else echo 'Right password/username but session failed to start';

後続のページでは、ユーザーがログインしているかどうかを確認します。

session_start();
if(isset($_SESSION['loggedInUser'])
{
 //rest of page
}
else echo 'you must log in';

ログアウトするとき、私は持っています

session_start();//if I don't have this the next line produces an error
session_unset();//destroys session variables
session_destroy();//ends session

ログアウト時に session_start() を呼び出さないようにしましたが、そこにない場合はメッセージが表示されますTrying to destroy uninitialized session。どうすればこれを修正できますか?

IP アドレスとユーザー エージェントに基づいてフィンガー プリントを作成することは推奨されますか? 複数のコンピューターがコンピューターラボなどにある場合、複数のコンピューターが同じ IP アドレスを共有でき、すべてのトラフィックがプロキシを通過し、動的な場合は同じコンピューターが IP アドレスを変更する可能性があるため、悪いと思います。一方、これはどのくらいの頻度で発生しますか?すべてのセッション ハイジャックを防ぐために、いくつかの有効な使用をブロックする価値があるかもしれません。

このトピックについて学ぶために私が読むべき評判の良い記事をお勧めできたとしても、それは素晴らしいことです。

5/6 の回答は 0 未満の票を持っています :( 反対票を投じる人がコメントできるので、何に注意すべきかがわかりますか?

4

5 に答える 5

28

まず、Mozilla WebAppSec Security Coding Guideline - Session ManagementおよびOWASP A3-Broken Authentication and Session Managementを読む必要があります。これらの要件を満たすようにPHP のセッション ハンドラーを構成できます。

防止する必要がある最初の欠陥は、A9-Insufficient Transport Layer Protectionです。つまり、誰かがFiresheep のようなツールを使用してセッションを乗っ取ってほしくありません。この攻撃は、ブラウザーが https 経由でのみセッション ID を送信するように強制することで防ぐことができます。

session.cookie_secure=1

httponly フラグを設定することで、攻撃者が XSS を使用してセッション ID を取得するのを防ぐことができます。

session.cookie_httponly=1

セッション ID を保存するために常にCookie を使用する必要があります。GET または POST 変数を使用してセッション ID を渡すことができる場合、攻撃者はセッション固定攻撃を使用してセッションを乗っ取る可能性があります。この攻撃についての別の考え方は、攻撃者が別のユーザーのためにセッションを作成することを望まないということです。

session.use_cookies=1
session.use_only_cookies=1

次に、CSPRNG から少なくとも 128 ビットのエントロピーがあることを確認します。*nix システムでは、以下を使用できます/dev/urandom

session.entropy_file="/dev/urandom"
session.entropy_length=16

セッション ハンドラがすべてではありません。クロスサイト リクエスト フォージェリ攻撃(別名 CSRF または「セッション ライディング」) とクロスサイト スクリプティング (XSS)については、まだ心配する必要があります。XSS を使用して、CSRF 保護を無効にすることができます (http_only Cookie を使用した場合でも!)。 クリックジャッキングは、攻撃者が不正なアクションを実行するために使用することもできます。

これらの構成オプションを設定したら、 を呼び出すだけsession_start()です。session_destroy()ユーザーがログアウトしたときにセッション呼び出しを破棄するのは簡単です。

于 2013-03-24T07:13:08.333 に答える
1

セッションを安全に破棄するには、次のコードを使用します。

session_start();
// Unset all session values
$_SESSION = array();
// get session parameters 
$params = session_get_cookie_params();
// Delete the actual cookie.
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
// Destroy session
session_destroy();

セッションを破棄するには、最初にセッションを開始する必要があります。

session_regenerate_id(); 関数は、ユーザーの新しいセッション ID を生成します。true (session_regenerate_id(true);) とともに使用すると、古いセッション ID は、新しいセッション ID を生成するときにサーバーから削除されます。すべてのページで新しいセッション ID を生成する理由は、ユーザーが絶えずセッション ID を変更するため、セッションのハイジャックを実行するのがはるかに困難 (ほぼ不可能?) になるためです。

( session_regenerate_id();の PHP.net マニュアルを参照)

ユーザーを認証するときは、IPアドレスやブラウザなどを常に確認する必要があります。これらは、サーバーへのリクエストで送信される一定のものであり、セッションの存続期間中は変更されません。変更された場合、何か危険なことが起こっていることがわかります. 私は常に、データベースにデータをクエリできるようにユーザー ID を格納する 2 つのセッション変数を作成し、もう 1 つはユーザーのパスワード、IP アドレス、およびブラウザー文字列をすべて 1 つのハッシュ (sha512) に格納します。

$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];

// Query Database and get hashed password

$login_check = hash('sha512', $password.$ip_address.$user_browser);

if($login_check == $login_string) {
     // Logged In!!!!
     return true;
} else {
     // Not logged in
     return false;
}

パスワードはセッションに保存されていますが、安全です。これは、パスワードがハッシュされ (この場合は 2 回)、セッション データがユーザーのコンピューターに保存されないため (Cookie と同様)、セッション ファイルに保存されるためです。

安全なログインと認証に関する記事を wikihow.com に書きまし

于 2013-03-19T22:19:29.910 に答える
0

あなたはただ書くことができます:

session_start(); // session should be started before it can be used.

ログインしたメンバーのユーザーIDを割り当てることができます。このために、ユーザー入力からユーザー名とパスワードを取得し、それをデータベースでチェックして、ユーザー ID を返すことができます。セキュリティを強化するために、たとえば次の文字列を使用できます。「デモ」と「テスト」は両方とも md5 だけで、次の方法でユーザー ID と混合します。

$userid=md5("demo").$userid.md5("test");// you can set any string instead of demo and test.

$_SESSION['userid']=$userid;

他のページで使用しながら、

session_start(); // If you are have not started it or included above code file in it.

使用中に文字列を知っているので、一致させて正確なユーザーIDを見つけ、コードで使用します。

それを破壊するには、次を使用します。

session_unset($_SESSION['userid']); // It will only unset the session userid completely. 

セッションを使用する前に、セッションを開始する必要があることを確認してください。より良い方法では、init.php などの 1 つのファイルでセッションを開始し、セッションを使用するすべての場所にそれを含めることができます。

于 2013-03-22T11:25:26.240 に答える
0

「start_session()」を使用せずにセッションを破棄するには、まず以下のようなアクティブなセッションがあるかどうかを確認します

$existingSessionId = session_id();
if ($existingSessionId != "")
{
     // Initialize the session.
     session_start();

     // Unset all of the session variables.
     $_SESSION = array();

     // If it's desired to kill the session, also delete the session cookie.
     // Note: This will destroy the session, and not just the session data!
     if (ini_get("session.use_cookies")) {
         $params = session_get_cookie_params();
         setcookie(session_name(), '', time() - 42000,
             $params["path"], $params["domain"],
             $params["secure"], $params["httponly"]
         );
     }

     // Finally, destroy the session.
     session_destroy();
}
else
{
     // No Active sessions
}

session_regenerate_id(true)、古いセッション ID を新しいセッション ID に置き換えるだけですが、古いセッション ID は設定解除されません。これは、session_destroy とセッション cookie の削除によって処理する必要があります。

ブラウザは、セッションが破棄されるたびにセッション Cookie をサーバーに送信します。PHP はこのセッション ID を取得し、start_session() を実行すると、ブラウザから送信されたセッション ID が使用されます。セッション Cookie を削除すると、session_start によって新しいセッション ID が生成されるため、session_regenerate_id() を呼び出す必要はありません。

于 2013-03-25T13:08:56.153 に答える
0

最初に を使用session_id()して、ユーザーが既にセッションを取得しているかどうかを判断できます。取得していない場合は、 を使用しますsession_start()

Lithium フレームワークのコード例:

/**
 * Starts the session.
 *
 * @return boolean True if session successfully started (or has already been started),
 *         false otherwise.
 */
protected static function _start() {
    if (session_id()) {
        return true;
    }
    ...
    return session_start();
}

通話後_start()、安全に通話できますsession_destroy()

于 2013-03-25T08:59:42.480 に答える