|
|
CVI. セッション処理関数(session)
PHPのセッションサポート機能は、複数回のアクセスを通じて特定のデー
タを保持する手段を実現するものです。これにより、よりカスタマイズさ
れたアプリケーションを構築し、自分の Web サイトのアピール度を増加
させることが可能となります。
Web サイトの訪問者にはセッションIDというセッションIDと呼ばれるユニークなIDが割りつけられ
ます。このIDは、ユーザー側にクッキーとして保存するか、または、URL
に埋め込みます。
セッションサポート機能により、任意の数の変数をリクエスト間で受けわたせる
ようになります。来訪者がサイトにアクセスした際、
PHP は特定のセッションIDがリクエストとともに送信されているかどうかを
(
session.auto_startが1の場合は)自動的に、または
(session_start() により明示的な、あるいは
session_register() により暗黙の)
要求を受けて確認します。
このIDが送信されている場合には、以前保存された変数が再現されます。
注意 |
session.auto_startをonとした場合、
オブジェクトをセッション変数に代入することができなくなります。
これは、セッションにおいてオブジェクトを再現するためには、
セッション開始前にクラス定義がロードされている必要があるためです。
|
全ての登録された変数は、リクエストが終了した後に、シリアル化されます。
未定義の登録変数は、未定義としてマーク付けされます。
これらの変数は、後でユーザーが定義しない限り、以降のアクセスにおいて
セッションモジュールにより定義されません。
注意:
セッション処理機能は、PHP 4.0 でサポートされました。
注意:
セッションを処理している時、
session_register()関数を使用するか
スーパーグローバル配列$_SESSIONへ新しいキーを
追加することにより変数が登録されるまで、セッションのレコードは作
成されないことに注意して下さい。これは、セッションが
session_start()関数により開始されている場合で
も真です。
外部リンク:
セッションモジュールは、セッションに保存した情報を見ることができる
のがそのセッションを作成したユーザーだけであることを保証することが
できません。セッションの完全性を積極的に守るには、そのセッションに
紐づく値に応じた追加措置が必要です。
セッションに運ばれるデータの重要性を評価し、必要な保護策を講じて
下さい。これには通常、お金があかり、ユーザの利便性を損なうことに
なります。例えば、簡単な社会工学的な策略からユーザを守るためには、
session.use_only_cookiesを有効にして下さい。
この場合、ユーザ側でクッキーが常に有効となっている必要があり
ます。そうでない場合、セッションは動作しません。
存在するセッションIDが第三者に洩れる手順は何種類かあります。
洩れたセッションIDにより、第三者が特定のIDに関連する全てのリソー
スにアクセスできるようになります。まず、セッションIDがURLにより伝
送される場合です。外部サイトにリンクを張っている場合、外部サイト
のreferrerログにセッションIDを含むURLが保存される可能性があります。
第二に、よりアクティブな攻撃者がネットワークのトラフィックをモニ
ターしている可能性があります。セッションIDが暗号化されていない場
合、セッションIDはネットワーク上を平文テキストで伝送されます。
解決策はサーバ上にSSLを実装し、ユーザにSSLを必ず使用させることです。
これらの関数は、標準モジュールの一部として利用可能であり、常に使用できます。 注意:
オプションで、Ralf S. Engelschallにより開発されたセッションの保
存用の共有メモリ(mm)を使用することも可能です。
をダウンロードし、インストールす
ることができます。このオプションは、Windowsプラットフォームでは
利用できません。mm用セッション保存モジュールは同一セッションのロッ
クに問題があるため、同時アクセスを保証することはできません。
ファイルにセッションを保存するためには、
(Solaris/LinuxまたはBSD上の/dev/md)ファイルシステムに
共有メモリを使用するためにより適当でしょう。
PHPのセッションサポートはデフォルトで有効となっています
セッションサポートを有効にしてPHPを構築したくない場合には、
configureにオプション--disable-sessionを指定する必要があります。
セッション記憶領域として共有メモリ(mm)を使用するには、PHPのconfigure
に--with-mm[=DIR]を指定します。
Windows版のPHPには
この拡張モジュールのサポートが組み込まれています。これらの関数を使用
するために拡張モジュールを追加でロードする必要はありません。 注意:
デフォルトでは、特定のセッションのすべての情報は
session.save_path INIオプションで指定されたディレクトリに生成される
ファイルに保存されます。
結びついている情報に関わらずセッション毎にひとつのファイルが生成されます。
セッションが開始され(ファイルが生成される)しかし何の情報も
そのファイルに書き込まれない場合もあります(サイズがゼロのファイルが残る)。
この振る舞いはファイルシステムを使っていることによる副作用であり、
カスタムセッションハンドラ(例:データベースを使ったもの)を
使う場合には何の情報も持たないセッションについて追跡しないように
することは可能です。
これらの関数の動作は、php.iniの設定により変化します。
表 1. セッションの設定オプション 名前 | デフォルト | 変更の可否 |
---|
session.save_path | "/tmp" | PHP_INI_ALL | session.name | "PHPSESSID" | PHP_INI_ALL | session.save_handler | "files" | PHP_INI_ALL | session.auto_start | "0" | PHP_INI_ALL | session.gc_probability | "1" | PHP_INI_ALL | session.gc_divisor | "100" | PHP_INI_ALL | session.gc_maxlifetime | "1440" | PHP_INI_ALL | session.serialize_handler | "php" | PHP_INI_ALL | session.cookie_lifetime | "0" | PHP_INI_ALL | session.cookie_path | "/" | PHP_INI_ALL | session.cookie_domain | "" | PHP_INI_ALL | session.cookie_secure | "" | PHP_INI_ALL | session.use_cookies | "1" | PHP_INI_ALL | session.use_only_cookies | "0" | PHP_INI_ALL | session.referer_check | "" | PHP_INI_ALL | session.entropy_file | "" | PHP_INI_ALL | session.entropy_length | "0" | PHP_INI_ALL | session.cache_limiter | "nocache" | PHP_INI_ALL | session.cache_expire | "180" | PHP_INI_ALL | session.use_trans_sid | "0" | PHP_INI_SYSTEM|PHP_INI_PERDIR | session.bug_compat_42 | "1" | PHP_INI_ALL | session.bug_compat_warn | "1" | PHP_INI_ALL | session.hash_function | "0" | PHP_INI_ALL | session.hash_bits_per_character | "4" | PHP_INI_ALL | url_rewriter.tags | "a=href,area=href,frame=src,input=src,form=fakeentry" | PHP_INI_ALL |
PHP_INI_* 定数の詳細と定義については、
ini_set()を参照して下さい。
セッション管理システムは、php.iniファイルに記述可能な多くの設定オ
プションをサポートします。以下に概要を示します。
- session.save_handler
string
session.save_handler は、セッションに関連す
るデータの保存および取得に使用されるハンドル名を定義します。デ
フォルトは、filesです。
session_set_save_handler()も参照して下さい。
- session.save_path
string
session.save_path は、保存ハンドラに渡される
引数を定義します。デフォルトのファイルハンドラを選択した場合、
ファイルが作成される場所のパスになります。デフォルトは、
/tmp です。
session.save_pathのパスの深さが2より大きい場
合、ガーベッジコレクションは行われません。
session_save_path()も参照して下さい。
オプションの引数としてN(数値)を指定できます。
これはセッションファイルを分散して保存する際に
ディレクトリ階層レベルを決定します。
例えば、'5;/tmp'とすると
/tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If
という位置にセッションファイルを生成します。
Nを使用するには、これらすべてのディレクトリが
事前に作成されている必要があります。
そのためのシェルスクリプトがext/sessionに
mod_files.shというファイル名であります。
また、0以上のNが指定されている場合には自動ガーベッジコレクション
が機能しないことに注意して下さい。詳細は php.ini を見てください。
また、Nを指定する場合は、
session.save_pathを"quotes"で囲う必要があります。
なぜならセパレータ(;) は
php.ini ではコメントとしても利用されているからです。
警告 |
この設定を/tmp (デフォルト)のようにどこか
らでも読み込み可能なディレクトリのままにしている場合、サーバ上
の他のユーザがこのディレクトリのファイルのリストを取得すること
により、セッションをハイジャックをすることが可能となります。
|
注意:
WindowsユーザがPHPのsession関数を使用するためには、この変数を変
更する必要があります。c:/tempのような有効
なパスを指定するようにして下さい。
- session.name
string
session.name はセッション名を指定し、
クッキー名として使用されます。
アルファベット文字のみで指定する必要があります。
デフォルトは、PHPSESSID です。
session_name()も参照して下さい。
- session.auto_start
boolean
session.auto_start はリクエスト開始時に
セッションモジュールがセッションを自動的に開始するかどうかを
指定します。デフォルトは、0(無効)です。
- session.serialize_handler
string
session.serialize_handler は、シリアル化また
はシリアル化データを復元するために使用されるハンドラの名前を定
義します。現在、( phpという名前の)PHP 内部
フォーマットおよび(wddxという名前の)WDDX が
サポートされています。WDDXは、PHP がWDDX サポート を有効にしてコンパイル
されている場合のみ使用可能です。デフォルトは、
php です。
- session.gc_probability
integer
session.gc_probabilityと
session.gc_divisorの組み合わせでgc
(ガーベッジコレクション)ルーチンの始動を制御します。
デフォルトは、1 です。
詳細はsession.gc_divisor
をご覧ください
- session.gc_divisor
integer
session.gc_divisorと
session.gc_probabilityの組み合わせで
すべてのセッションの初期化過程でgc(ガーベッジコネクション)プロセス
も始動する確率を制御します。確率は gc_probability/gc_divisor
で計算されます。例えば、1/100は各リクエスト毎に1%の確率でGCプロセスが
始動します。
session.gc_divisorのデフォルトは100です。
- session.gc_maxlifetime
integer
session.gc_maxlifetime は、データが'ごみ'と
みなされ、消去されるまでの秒数を指定します。
注意:
デフォルトのファイルに基づくセッションハンドラを使用している場
合、使用するファイルシステムは、アクセス時間(atime)を記録できる
必要があります。Windows FATはこれができないため、
FATファイルシステムまたはatimeの記録ができない他のファイルシス
テムで問題を発生した場合は、セッションのガベージコレクト処理を
行う他の手段を用意する必要があります。
PHP4.2.3以降、atimeの代わりにmtime(更新時刻)が使用されます。
このため、atimeが利用できないファイルシステムでの問題は無くなりました。
- session.referer_check
string
session.referer_check には、HTTP Referer に
おいて確認を行う文字列を指定します。Refererがクライアントにより
送信されており、かつ、指定した文字列が見付からない場合、埋め込
まれたセッションIDは無効となります。デフォルトは空の文字列です。
- session.entropy_file
string
session.entropy_file は、
セッションIDを作成する際の別のエントロピソースとして使用する
外部リソースへのパスを指定します。
例としては、多くの UNIX で利用可能な /dev/random
または /dev/urandom があげられます。
- session.entropy_length
integer
session.entropy_length は、前記のファイルから
読みこむバイト数を指定します。デフォルトは、0
(無効)です。
- session.use_cookies
boolean
session.use_cookiesによりクライアント側にセッ
ションIDを保存する際にクッキーを使用するかどうかを指定します。デ
フォルトは1 (有効)です。
- session.use_only_cookies
boolean
session.use_only_cookiesは、
このモジュールがクライアント側へのセッションIDの保存に
Cookieのみを使用することを指
定します。デフォルトは、0 (無効、下位互換性の
ため)です。この設定を有効にすることにより、セッションIDをURLに埋
め込む攻撃を防ぐことができます。この設定は、
PHP 4.3.0で追加されました。
- session.cookie_lifetime
integer
session.cookie_lifetimeは、ブラウザに送信す
るクッキーの有効期間を秒単位で指定します。値0は、"ブラウザを閉じ
るまで"を意味します。デフォルトは、0です。
session_get_cookie_params()および
session_set_cookie_params()も参照して下さい。
- session.cookie_path
string
session.cookie_pathによりsession_cookieで設
定するパスを指定します。デフォルトは/です。
session_get_cookie_params()および
session_set_cookie_params()も参照して下さい。
- session.cookie_domain
string
session.cookie_domainによりsession_cookieで
指定するドメインを指定します。デフォルトでは指定されません。
session_get_cookie_params()および
session_set_cookie_params()も参照して下さい。
- session.cookie_secure
boolean
session.cookie_secureは、
セキュアな接続を通じてのみCookieを送信できるかどうかを指定します。
デフォルトは、offです。
この設定は、PHP 4.0.4で追加されました。
session_get_cookie_params()および
session_set_cookie_params()も参照して下さい。
- session.cache_limiter
string
session.cache_limiterにより
セッションページにおけるキャッシュ制御の方法
(none/nocache/private/private_no_expire/public)
を指定します。デフォルトは、nocacheです。
session_cache_limiter()も参照して下さい。
- session.cache_expire
integer
session.cache_expireによりキャッシュされた
セッションページの有効期間を分単位で指定します。
このオプションは、nocacheリミッタに関しては効果がありません。
デフォルトは、180です。
session_cache_expire()も参照して下さい。
- session.use_trans_sid
boolean
session.use_trans_sidは、透過的なセッション
IDの付加をするかどうかを指定します。
デフォルトは、0(無効)です。
注意:
PHP 4.1.2より前のバージョンでは、このオプションは
--enable-trans-sidにより
コンパイル時に有効とされていました。
PHP 4.2.0以降、trans-sid機能は常にコンパイルされます。
URLに基づくセッション管理は、Cookieに基づくセッション管理と比べ
てセキュリティリスクが大きくなります。例えば、ユーザは、emailに
より友人にアクティブなセッションIDを含むURLを送信する可能性があ
り、また、ユーザは自分のブックマークにセッションIDを含むURLを保
存し、常に同じセッションIDで使用するサイトにアクセスする可能性
があります。
- session.bug_compat_42
boolean
PHP versions 4.2.0 and lower have an undocumented feature/bug that
allows you to to initialize a session variable in the global scope,
albeit register_globals
is disabled. PHP 4.3.0 and later will warn you, if this feature is
used, and if
session.bug_compat_warn is also enabled.
- session.bug_compat_warn
boolean
PHP versions 4.2.0 and lower have an undocumented feature/bug that
allows you to to initialize a session variable in the global scope,
albeit register_globals
is disabled. PHP 4.3.0 and later will warn you, if this feature is
used by enabling both
session.bug_compat_42
and
session.bug_compat_warn.
- session.hash_function
integer
session.hash_function allows you to specify the hash
algorithm used to generate the session IDs. '0' means MD5 (128 bits) and
'1' means SHA-1 (160 bits).
注意:
This was introduced in PHP 5.
- session.hash_bits_per_character
integer
session.hash_bits_per_character allows you to define
how many bits are stored in each character when converting the binary
hash data to something readable. The possible values are '4' (0-9, a-f),
'5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ",").
注意:
This was introduced in PHP 5.
- url_rewriter.tags
string
url_rewriter.tagsは、透過的なセッションIDの
付加機能が有効となった場合に、セッションIDを含めるために書き換
えられるHTMLタグを指定します。デフォルトは、
a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=
です。
注意:
XHTML に適合させたい場合には form エントリは削除し、
formフィールドの前後に<fieldset> タグを使ってください。
track_varsおよび
register_globals
設定はセッション変数の保存および回復方法に影響を与えます。
この拡張モジュールはリソース型を全く定義しません。
これらの定数は、この拡張モジュールで定義されており、
この拡張モジュールがPHP内部にコンパイルされているか実行時に動的にロー
ドされるかのどちらかの場合のみ使用可能です。
- SID
(string)
"name=ID"形式でセッション名とセッションIDを格納している定数。
セッションIDがセッションクッキーに適切にセットされている場合には空文字列が入る。
注意:
PHP 4.1.0以降、$_SESSIONは、
$_POST, $_GET,
$_REQUEST等のようにグローバル変数として利用可
能です。$HTTP_SESSION_VARSと異なり、
$_SESSIONは常にグローバルです。そこで、
global
は$_SESSIONの場合は不要です。
このドキュメントでは、$_SESSION をあらゆる場
所で使用していることに注意して下さい。もし前者を使用したい場合に
は、$_SESSIONを
$HTTP_SESSION_VARSで置き換えることができます。
また、$_SESSIONを使用する前に
session_start() を用いてセッションを開始して
おく必要があることに注意して下さい。
連想配列$_SESSIONのキーは、PHPの通常の変数名
と同じ制限があります。すなわち、数字で始まることはできず、文字ま
たはアンダースコアで始まる必要があります。
詳細については、本マニュアルの
変数の節を参照して下さ
い。
register_globals
が無効の場合、グローバル連想配列$_SESSIONのメ
ンバーのみがセッション変数として登録されます。
回復されたセッション変数は、配列$_SESSIONでの
み利用可能です。
セキュリティとコードの可読性のために$_SESSION
(またはPHP 4.0.6以前は$HTTP_SESSION_VARS)の使用
が推奨されます。$_SESSIONの場合、
session_register(),
session_unregister(),
session_is_registered()は不要です。ユーザは、
通常の変数と同様にセッション変数にアクセス可能
です。
例 1.
$_SESSIONで変数を登録
<?php
session_start();
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
} else {
$_SESSION['count']++;
}
?>
|
|
例 2.
register_globals
が無効な場合に、$_SESSIONに登録されている変
数の登録を解除する
<?php
session_start();
unset($_SESSION['count']);
?>
|
|
注意 |
unset($_SESSION)によって
全ての$_SESSIONを初期化してはいけません。
$_SESSIONスーパーグローバル変数を用いた
セッション変数の登録ができなくなってしまうからです。
|
警告 |
セッション変数において参照を使用することはできません。
他の変数への参照の再現する方法がないからです。
|
例 3.
register_globals
が有効な場合に、$_SESSIONを用いて登録した後、
変数の登録を解除する
<?php
session_start();
session_unregister('count');
?>
|
|
register_globals
が有効な場合、全てのグローバル変数はセッション変数として登録するこ
とが可能で、セッション変数は対応するグローバル変数として回復されま
す。PHPは、どのグローバル変数がセッション変数として登録されるのか
を知る必要があるため、ユーザは、変数を
session_register()関数で登録する必要がありま
す。しかし、$_SESSIONの場合は、エントリを設定
するだけでこれを行う必要はありません。
例 4.
register_globals
が有効な場合に、変数を登録する
<?php
if (! isset($_SESSION['count'])) {
$_SESSION['count'] = 1;
} else {
$_SESSION['count']++;
}
?>
|
|
register_globals
が有効な場合、グローバル変数と$_SESSIONの
エントリは、前のセッションインスタンスで登録されたセッション変数
の同じ値を参照することになります。
PHP 4.2.3とそれ以前のバージョンのみに関係する問題があります。
session_register()により新しいセッショ
ン変数を登録する場合、グローバルスコープのエントリと
$_SESSIONのエントリは、次の
session_start()まで同じ値へのリファレンスとは
なりません。
すなわち、グローバル変数への修正は、$_SESSION
のエントリには反映されません。PHP 4.3では修正されています。
セッションIDの通知を行うためには次の二つの方法があります。
sessionモジュールは、両方の方法をサポートします。
Cookieは最適ですが、(クライアントがCookieを受け入れない可能性が
あるため)信頼性がなく、これに依存することができません。2番目の方
法は、セッションIDを直接URLに埋め込みます。
PHPには、透過的にリンクを変換する機能を有しています。
PHP 4.2以降を使用していない場合、PHP構築時にこの機能を有効にして
おく必要があります。UNIX環境では、
--enable-trans-sidをconfigureに指定して
下さい。この構築オプションと実行時オプション
session.use_trans_sidが有効な場合、
相対URIは自動的にセッションIDを含むように変換されます。
注意:
arg_separator.output
php.ini ディレクティブにより、引数セパレータをカスタマイズする
ことができます。XHTMLに完全準拠するためには、ここに
& を指定して下さい。
もしくは、常に定義されている定数SIDを使用する
こともできます。クライアントが適当なセッションクッキーを送信しな
かった場合、この定数はsession_name=session_id
の形式となります。他方、送信された場合には、この定数は空の文字列
に展開されます。このため、この定数を無条件にURLに埋め込むことがで
きます。
次の例は、変数の登録法および SID を用いて他のページに正しくリンク
する方法のデモです。
例 5. 単一のユーザーに関するヒット数を数える
<?php
if (!session_is_registered('count')) {
session_register('count');
$count = 1;
} else {
$count++;
}
?>
<p>
こんにちは、あなたがこのページに来たのは<?php echo $count; ?>回目ですね。
</p>
<p>
続けるには、<A HREF="nextpage.php?<?php echo strip_tags (SID)?>">ここをクリック</A>
して下さい。
</p>
|
|
XSSに関係する攻撃を防止するためにSIDを出力する際に、
strip_tags()を使用します。
PHPをコンパイルする際に
--enable-trans-sid を使用した場合、
上の例のように SID を出力する必要はありません。
注意:
相対URLでないURLは外部サイトを指していると仮定され、SIDが追加
されません。これは、SIDを外部のサーバに開示することはセキュリティ
上のリスクとなる可能性があるためです。
add a note
User Contributed Notes
セッション処理関数(session)
peavey at pixelpickers dot com
10-Mar-2005 03:09
Stoiev is absolutely right, this problem is a real pain in the ...
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
instead of this:
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
But this solution might work out better...
Try setting an own host/path?$id=session_id()&anothervar=someval and call ini_set('session.use_trans_sid', 0); BEFORE starting the session. It doesnt matter where you call it (document itself oder included).
It prevents PHP from putting the PHPSESSID after every get-String...
Best,
Peavey
helvecio_oliveira at yahoo dot com dot br
04-Mar-2005 11:41
This is a simple code, to read all kind of session informations, for all php user in a UN*X Server.
All php session information, are stored in tmp files:
Ex:
ls -1 /tmp/sess_*
/tmp/sess_3a0c122ea49eab3a9cea37d426463945
/tmp/sess_63fe2dda925f836a454368ee8b157ba6
/tmp/sess_8649e55af46746c3f899cf316006e4b5
/tmp/sess_8ffa7e35e7c0be16a213e97602aba31e
The code below, is a sugestion to count and identify users on-line:
<?
$_SESSION["LogonUserVar"]="user.name";
?>
<?
$files=f_ls();
foreach($files as $path){
if($fsize =filesize($path)){
$fp = fopen($path,'rb');
$lines.=fgets($fp,$fsize);
fclose($fp);
$fields = explode(";",$lines);
$fsize =filesize($fullPath);
foreach($fields as $field){
if(ereg("^LogonUserVar",$field)==true){
$aName=explode(":",$field);
$name=str_replace('"','',$aName[2]);
$aUser[$name]=$aUser[$name]+1;
}
}
}
}
$c=0;
$html1= "<html><body>".gtime()."<br>";
foreach($aUser as $user=>$nSessions){
$html3.= "<tr><td>".$user."</td><td>".$nSessions."</td></tr>";
$c++;
}
$html2="<br>$c users on-line:<br><br><table><td>User</td><td>nSessions</td>";
$html=$html1.$html2.$html3."</table></body>";
print $html;
function f_ls(){
$command="ls -1 /tmp/sess_*";
if ($proc = popen("($command)2>&1","r")){
while (!feof($proc)) $contents .= fgets($proc, 1000);
}
pclose($proc);
return explode("\n",$contents);
}
function gtime() {
return date('d/m/Y H:i:s');
}
?>
anders
02-Mar-2005 02:15
To juroh at juroh dot sk:
It's true that session variables are stored on-server, but for the server to know which session the user is using, a cookie is used. If you check your cookie cache, you'd see that the only session-related information you find in your cookie is a session id, no matter how much information you store in $_SESSION.
mat3582 at NOSPAM dot hotmail dot com
28-Feb-2005 10:36
Outputting a pdf file to a MSIE browser didn't work (MSIE mistook the file for an Active-X control,
then failed to download) untill I added
<?php
ini_set('session.cache_limiter',"0");
?>
to my script. I hope this will help someone else.
sae_zzz at yahoo dot com
22-Feb-2005 09:16
Session yang lain:
form.htm
<html>
<body>
<form action="login.php" method="post">
username : <input type="text" name="user"><br>
password : <input type="password" name="pass"><br>
<input type="submit" name="submit" value="kirim">
</form>
</body>
</html>
login.php
<?php
session_start();
if(($_POST['user']=="a3") && ($_POST['pass']=="a3"))
{$_SESSION['user']=$_POST['user'];
echo("login benar<br>
<a href=\"main.php\">Main Page</a>");}
else
{session_destroy();
echo("login salah<br>
<a href=\"form.htm\">back</a>");
exit;
}
?>
beliexp at yahoo dot com
17-Feb-2005 07:29
This is for tom(AT)darlingpet.com
I think that what you are explaining happens because what you have to put inside $_SESSION[] is the name of a variable and there are rules for giving names. I don't remeber all of them but I'm pretty sure one of them is that a variable name or identifier can't start with a number. That's why your solution works because your variable names would be i1, i2, ...
You could always try $_SESSION[my_array[$i]], you may find it more handy.
beliexp at yahoo dot com
17-Feb-2005 07:15
This is a note for someone who posted this:
I'm having toubles using sessions on my local (XP)machine.
I'm using a loginscript that works fine on line but it won't work at home...
Right, I read on the session_start() section of the manual, from the user's notes, that this problem happens in Windows because it doesn't keep the session id and opens a new one every time you call session_start(). I've been where you are too. Annoying, uh? Well, as a solution it gives you a few options:
1. You can always set the same id, which is a bit of a cheeky solution, but it works ( session_start('123456');)
2. You can pass the session_id from the first time you start a session through the URL or as a hidden item in a form and then recover it with HTTP_GET_VARS or HTTP_POST_VARS, respectively.
3. There is another one I don't remember very well but is about changing the header options. For this one you may go to the session_start() section to the user's notes.
Well, hope this can help
Good luck with your thing!!
john at digitizelife dot com
10-Feb-2005 06:30
Here is a simple way to secure a single page (index.php) using sessions. Create a file called index.php and paste the following code;
----------------------------------------------------
<?
session_start();
$un = "Bob";
$pw = "fubar";
if ($action == "logout") {
session_unset();
}
if ($action == "login") {
if ($put_un == $un) {
if ($put_pw == $pw) {
$_SESSION['auth'] = true;
} else {
$error = "incorrect password.";
}
} else {
$error = "incorrect username.";
}
}
if ($_SESSION['auth'] == true) {
} else {
$view = "login";
}
?>
<html>
<title>Secure Area</title>
<body>
<? if ($view == "login") { ?>
<form action="index.php" method="post">
user<br>
<input type="text" name="put_un"><br>
password<br>
<input type="password" name="put_pw">
<input name="action" type="hidden" id="action" value="login"><br>
<input type="submit" name="Submit" value="login"><? echo "$error<br>"; ?>
</form>
<? } if ($_SESSION['auth'] == true) { ?>
<! -- SECURE CONTENT -->
<a href="index.php?action=logout">logout</a>
<? } ?>
</body>
</html>
-----------------------------------------------------
Simply set your user name and password in the "user settings" area and put your secure content in the "SECURE CONTENT" area.
You can login using a URL like this;
You can logout using the following link;
Be sure that any addtional PHP code you wish to use should be placed in the "secure code" or the "non-secure code" sections.
Weird Silence
01-Feb-2005 01:24
If you are in need of using shared sessions across multiple servers, and don't want to use a database for it (lots of overhead), we've created a distributed session handler that uses memcached - Check it out at - It's free and open source!
It uses Danga.com's memcached: - Very cool stuff!
trev at beammeupnowplease dot com
03-Jan-2005 04:09
As mentioned by toxalot, you can't turn off session.use_trans_sid on an individual script basis until PHP5.
However, if you use ini_set('url_rewriter.tags', ''); at the top of your script this will stop the SID being written to the URL's in PHP4.
Hopefully will save someone else a frustrating couple of hours.
Trev
jphansen at uga dot edu
23-Dec-2004 03:23
If you assign a session subscript/key to the same name as a variable, the session variable will be volatile and lost upon navigating.
For example, if passing a setting that you want in $_SESSION, don't do this:
<?
$setting = $_REQUEST['setting'];
if (!empty($setting))
$_SESSION['setting'] = $setting;
?>
Instead, rename $setting or $_SESSION['setting'].
Xenon_54
19-Dec-2004 06:27
The session support does not use the IP address for validation. It is based on cookies and URL rewriting.
The reason you lose your session when closing your browser and reconnecting to your ISP (so you are changing your IP), is that sessions are only valides for the visit on your web site, not more.
Changing your IP address will not affect your session except if you close your browser.
Michael Wells
22-Nov-2004 05:04
If you are trying to share sessions across a cluster of servers, and don't want to use NFS, or a relatively heavy and slow RDBMS, there is an excellent tool called ShareDance that can do it over a simple TCP protocol. ShareDance comes complete with a PHP interface example and works 'out of the box' for me.
My thanks to Frank Denis for writing this elegant, valuable piece of software.
Audun Rundberg
14-Nov-2004 04:50
If you're using header('Location:' . $url) to redirect the user to another page, you should use session_write_close() to save session data before the redirect. $_SESSION is normally serialized and written to the harddrive when the script ends.
Example:
<?php
$_SESSION["Message"] = "The task was completed.";
session_write_close();
header('Location:' . $_SERVER["PHP_SELF"]);
?>
Without session_write_close(), this next piece of code would not output "The task was completed". (Assuming that this code is in place where the user was redirected.)
<?php
echo $_SESSION["Message"];
?>
toxalot
15-Sep-2004 06:54
session.use_trans_sid is stated as being changeable PHP_INI_ALL, but it is not changeable with ini_set until PHP 5
References:
irm at in3activa dot com
13-Sep-2004 06:57
Warnings :
session.bug_compat_42 and bug_compat_warn
Warnings may appears even if your code is correct,
because some asumptions of the developpers.
In practice, these warnings are automatic when your code results in something like:
$_SESSION['var']= NULL;
That is, the code assume that the programmer tried
to assign a unavailable (=NULL) variable because
register_globals is off.
Solution: assign anything but NULL. For example:
$_SESSION['var']= is_null($var) ? 0 : $var;
cryogen AT mac dot com
10-Sep-2004 12:02
Although this IS mentioned in the PHP manual, it is not very clear and can lead to some very hard to track down bugs.
When REGISTER_GLOBALS is ON on a server, local variables of the same name as a session variable can leak their values into the session during a POST or GET.
For example, if you run script "SESS_TEST1.PHP" below, the local var $animal will bleed its value of "I am an Elephant" into the session variable $_SESSION['animal'], which should have a value of "I am a Monkey". Beware!
<?php
session_start();
$_SESSION['animal'] = 'I am a Monkey';
$animal = 'I am an Elephant';
$value = 249;
echo "<script>window.location=\"sess_test2.php".
"?animal=$animal&value=$value\"</script>";
?>
<?php
session_start();
$animal = $_REQUEST['animal'];
$value = $_REQUEST['value'];
echo "SESSION['animal'] = ".$_SESSION['animal']." (should say \"I am a Monkey\")<br/>";
echo "\$animal = ".$animal."<br/>";
echo "\$value = ".$value."<br/>";
?>
voisine at yahoo dot com
09-Sep-2004 05:05
It seems the issue with $_SESSION being slow has been addressed. Accessing $_SESSION is just as fast as any other superglobal array. It is serialized and written to disk only once at the end of the request, not after each access as some of the previous comments seemed to imply. Some benchmarking info for assigning values to both $_SESSION and $_GET a hundred thousand times or so:
$_SESSION: 0.380021095276
$_GET: 0.50522685051
Dopey
03-Sep-2004 06:06
Be careful when using the Content-Length header with session.use_trans_sid enabled. Technically, it might not be a bug, but PHP does not update the header when it adds the session ID to links in a page. The result is that only partial content is shown in a browser.
In short: if you use ob_get_length to figure out Content-Length, turn session.use_trans_sid off!
root[noSPAM]cyberdark.net
17-Aug-2004 03:55
A common problem with session.auto_start, when activated in php.ini file, is the fact that if you've php objects inside the session classes must be loaded before session in started. You'll run into trouble then...
To avoid this, if you cannot ask your sysadmin to modify the php.ini file, add this line to your .htaccess wherever you need it in your application (usually on top of your app):
php_value session.auto_start 0
bcage at tecdigital dot net
23-Jun-2004 08:24
[Quote]
Someone posted a message here saying you should just all use the MM shared memory management for sessions. I'd like to CAUTION EVERYONE against using it!
I run a few webservers for a webhosting company, and we quickly ran in to PHP pages segfaulting Apache for unknown reasons, until we did a test with sessions. It turns out that the sessions, while using the mm stuff, couldn't keep the data right. I guess it was to do with the file locking issue mentioned in the documentation here (I didn't notice this until now!).
Anyways, if you run a Unix machine that can map virtual memory to a mount point (like tmpfs or shm or whatever it may be called), use this instead. It's volatile like mm, but works. Only thing you don't get is hidden session info so that other people don't know how to open it easily - but it's better than trying to use mm and having the webserver crash all the time!
[EndQuote]
You're totally right, in my server (FreeBSD 5.2) when using mm to handle sessions, dotProject wouldn't even start, it crashed when accessing index.php. This was solved by creating a swap-backed memory disk with the following options
rw,-s60000,,-b=4096,-f=512,-i=560,-c=3,-m=0,nosuid,nodev,nosymfollow
schulze at telstra dot com dot not dot this dot bit
06-Jun-2004 11:10
sessions not sticking and cookies not setting with IE? took me ages to find the problem.
you need a 'compact privacy policy'! it's not hard once you know how!
this was too much for me:
but is very easy to apply
and a visit to this site is very worthwhile:
happy PHP to all!
Erich
Osmos
09-May-2004 01:13
Note to the massage from "setec at freemail dot it" (01-Mar-2004 01:41).
For more flexibility I suggest replacing the string
<?php
_safe_set ($parse_url["scheme"], "http");
?>
with the following one:
<?php
_safe_set ($parse_url["scheme"], $_SERVER["HTTPS"] ? "https" : "http");
?>
Afternoon
04-May-2004 07:28
I found a good solution to create a persistent session by storing a persistence flag, ironically, in the session itelf. I start the session (which sends a Set-Cookie with no expiry time), read the flag and then, if the user wants a persistent session, stop and restart the session with the expiry time set using session_set_cookie_params, which then sends a cookie with a good expiry time. This solution has been quickly tested with all major browsers and seems to work.
I have outlined the whole process in my blog:
Rikahs Design
14-Apr-2004 07:10
When setting url_rewriter.tags parameter in php.ini, make sure that you put quotes around the string portion like this:
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
or the PHP won't know what tags to insert the session id into. My web host has a relatively current version of PHP and they still didn't have this parameter configured by default.
nate at 8networks dot com
16-Mar-2004 06:16
Re: $_SESSION can be slooowwwww
Remember $_SESSION varibles are stored and read from a physical drive most of the time. Beside implementing a virtual drive configuration you can also use a faster drive or implement RAID to double access time on the drives you use now.
setec at freemail dot it
01-Mar-2004 09:41
This is a usefull code I have done that allows to make a redirection using headers with full support for sessions and HTTP 1.1.
<?php
function session_redirect ($url = "")
{
function _safe_set (&$var_true, $var_false = "")
{
if (!isset ($var_true))
{ $var_true = $var_false; }
}
$parse_url = parse_url ($url);
_safe_set ($parse_url["scheme"], "http");
_safe_set ($parse_url["host"], $_SERVER['HTTP_HOST']);
_safe_set ($parse_url["path"], "");
_safe_set ($parse_url["query"], "");
_safe_set ($parse_url["fragment"], "");
if (substr ($parse_url["path"], 0, 1) != "/")
{
$parse_url["path"] = dirname ($_SERVER['PHP_SELF']) .
"/" . $parse_url["path"];
}
if ($parse_url["query"] != "")
{ $parse_url["query"] = $parse_url["query"] . "&"; }
$parse_url["query"] = "?" . $parse_url["query"] .
session_name () . "=" .
strip_tags (session_id ());
if ($parse_url["fragment"] != "")
{ $parse_url["fragment"] = "#" . $parse_url["fragment"]; }
$url = $parse_url["scheme"] . "://" . $parse_url["host"] .
$parse_url["path"] . $parse_url["query"] .
$parse_url["fragment"];
session_write_close ();
header ("Location: " . $url);
exit;
}
?>
spagmoid at yahoo dot NOSPAMcom
13-Dec-2003 10:24
WARNING: Yet another dangerous/possibly faulty thing has been added to the session handler, without adequate explanation of it's effects.
referer_check sounds like a great idea - but if you don't understand what it really does, your site could have problems that are very difficult to track down. Especially if you have 2 sites that link back and forth. Consider this: you have a user logged in, happily enjoying a cookie-based session. He clicks on a link to another site. He then clicks a link that returns him to your site, and finds that he is locked out. His session has been reset, even though the SID was not in the URL, it was safely in a cookie. Now consider that he had another browser window open, filling out a 5-page form. When he submits, it will all be lost. A combination of factors on my site has resulted in 10% of new signups being completely LOCKED OUT the last few weeks. For now, DO NOT USE referer_check.
You could easily write your own, that only checks the URL/POST for the session info, rather than the cookie. Then you would also be able to log when it happens. I think this "feature" should be removed - sessions are too important and fragile to be toyed around with.
dan
06-Dec-2003 06:34
If you understand how sessions work in PHP, here's a FREE (GNU) and very well coded custom session handler "package" for use with MySQL. This is extremely useful if you want PHP to handle sessions using a MySQL database, ie, you want to overcome the "slooowww" access to $_SESSION with default settings, you like the idea of custom session handling but are too lazy to set it up (like me =)), you are hosted on a shared server and need session info secured, you'd like to see a really well coded sample of how to take advantage of custom session handling, etc...
The documentation is minimal, so read up on the session.* variables, explore the code, and have fun with it!
To those using a third-party web host, I suggest that you disable persistant connections. Also, note that after going through the "Class Configuration" on the website, the options you selected are very easy to change in the custom generated configuation file.
Thanks to Cheetah Soft, Inc for making it available under GNU!
gzink at zinkconsulting dot com
03-Dec-2003 10:57
[Editors note: I've just benchmarked this, and over a 100 element array the results are as follows: (average over 10 runs)
Standard Array: 0.102ms
$_SESSION: 0.197
This is in the extremely unlikely case of having to loop through 100 elements in a session variable. Remember, if you have that many elements in your session, something is wrong.]
A small warning! $_SESSION can be slooowwwww....
I've never heard of this, but it turns out $_SESSION is much slower than any regular array, even an exact copy of $_SESSION. Copying large amounts of data in/out of $_SESSION is seriously slow and each access to $_SESSION is noticeably slower than regular arrays.
The lesson I learned? Don't use $_SESSION in loops that run very much. Even copying data from $_SESSION before the loop won't help a lot if there's a lot of data there due to a delay that can be pretty hefty, almost equal to working directly on $_SESSION with foreach() and actually slower than working directly on $_SESSION if you need to put the data back in the array in my experience. It's better to pass the data another way if possible, i.e. save the SQL query and re-run, store in a database, etc.
Just a warning for those who may be using this array in medium to large loops or trying to pass lots of data. I hope it saves you the hours of optimizing I've had to spend!
-Galen
pautzomat at web dot de
19-Nov-2003 08:05
Be aware of the fact that absolute URLs are NOT automatically rewritten to contain the SID.
Of course, it says so in the documentation ('Passing the Session Id') and of course it makes perfectly sense to have that restriction, but here's what happened to me:
I have been using sessions for quite a while without problems. When I used a global configuration file to be included in all my scripts, it contained a line like this:
$sHomeDirectory = '
which was used to make sure that all automatically generated links had the right prefix (just like $cfg['PmaAbsoluteUri'] works in phpMyAdmin). After introducing that variable, no link would pass the SID anymore, causing every script to return to the login page. It took me hours (!!) to recognize that this wasn't a bug in my code or some misconfiguration in php.ini and then still some more time to find out what it was. The above restriction had completely slipped from my mind (if it ever was there...)
Skipping the 'http:' did the job.
OK, it was my own mistake, of course, but it just shows you how easily one can sabotage his own work for hours... Just don't do it ;)
zombie (at) localm (dotto) oh - arr-gee
09-Aug-2003 11:42
I don't know if this is obvious or not, but since it took me forever to figure it out, i will post it...
<?
ini_set("session.cookie_domain",".artattack.to");
session_start();
print_r($_SESSION);
?>
This will allow cookies/session info to be available to artattack.to as well as its Cnames (ex: www.artattack.to, zombie.artattack.to, squirrel.nut.artattack.to)
All this does is set the domain attribute of the set_cookie() style function sessions use since a "session" is just a cookie on your computer that php looks for that contains your session id.
I assume, therefor that you can do something of the like for cookies in javascript and such.
The silly thing about all this is that it is a "feature" of cookies to be able to span c names/subdomains. This is exactly why set_cookie() has an option domain argument. However, it seems like most of the people have had my problem have not gone in that direction or at least not posted a correct solution on the web. Google just gave me lots of hacked solutions. In my quest, i read articles about apache hacks, setting the serverside session storage folder, using file() from a sub on a file doing a print_r on the session located ont he main server, etc etc. I guess if you really know how cookies work (which i thought i did before all this mess but obviously not) then this problem seems like not much of a problem at all and a simple missunderstanding of what cookies do and why they are cool.
Wizards vs Hackers.
I hope this helps someone.
--
Blaine
webmaster of the art attack
orion at dr-alliance dot com
08-Aug-2003 10:52
Session ID's wont be carried over through meta refreshes, so make sure you add the variables (in GET format) to the URL.
IE )
<meta http-equiv=\"refresh\" content=\"1;URL=index.php?PHPSESSID=$PHPSESSID\">
quinn at strangecode dot com
19-Mar-2003 10:10
Do not 'global' a superglobal! If you register a $_SUPERGLOBAL as a global variable (as in... global $_SESSION; within a function definition) strange things happen with some versions of PHP (PHP 4.2.3 on my MacOS X powerbook, but not my PHP 4.2.3 RH 7.3 linux machine). In the case I found, $_SESSION and $HTTP_SESSION_VARS would not reference the same data, and unsetting or accessing the data was inconsistant. Didn't test very far, but obviously this should not be done, and it did wreck havoc for me.
tim at digicol dot de
04-Feb-2003 06:14
Be careful when using ini_set to change the session.gc_maxlifetime value locally for your script:
You will trash other people's sessions when garbage collection takes place (and they will trash yours) regardless of their (your) intended session.gc_maxlifetime, because the session_name is not taken into account during garbage collection.
Create an own directory and set session.save_path to it, so that your session files don't get mixed.
nutbar at innocent dot com
17-Jan-2003 10:44
Someone posted a message here saying you should just all use the MM shared memory management for sessions. I'd like to CAUTION EVERYONE against using it!
I run a few webservers for a webhosting company, and we quickly ran in to PHP pages segfaulting Apache for unknown reasons, until we did a test with sessions. It turns out that the sessions, while using the mm stuff, couldn't keep the data right. I guess it was to do with the file locking issue mentioned in the documentation here (I didn't notice this until now!).
Anyways, if you run a Unix machine that can map virtual memory to a mount point (like tmpfs or shm or whatever it may be called), use this instead. It's volatile like mm, but works. Only thing you don't get is hidden session info so that other people don't know how to open it easily - but it's better than trying to use mm and having the webserver crash all the time!
jules at dsf dot org dot uk
16-Jan-2003 09:13
There are a few comments above about how using sessions might not be secure, but quite apart from session hijacking, there is a mistake that I think a lot of people are making at the moment that everyone needs to stop and make sure they aren't one.
This mistake arises from having the 'register_globals' setting on.
Take the following example code which is meant to maintain a session variable for whether a user is logged in and allow them to log in using a username and password if they aren't logged in, or give an option for logging out if they are:
<?php
session_register ("logged_in");
if (!strcmp($user, "user") && !strcmp($pass, "password"))
$logged_in = 1;
if ($logout)
$logged_in = 0;
if ($logged_in)
echo "logged in. <A href=\"sestest.php?logout=1\">log out</A>";
else
echo "<FORM action=sestest.php method=get>User: <INPUT type=text name=user><BR>Password: <INPUT type=text name=pass><BR><INPUT type=submit></FORM>";
?>
This works fine under normal use, but an attacker can log in without knowing the username or password by accessing '.../sestest.php?logged_in=1', which will set the session variable 'logged_in' to the value 1.
However, once a session variable has been set, it cannot be overridden in this fashion, so one solution is to use code like the code shown above (which has no explanation attached as to why you should do it that way) that uses session_is_registered:
<?php
session_start ();
if (!session_is_registered ("logged_in"))
{
$logged_in = 0;
session_register ("logged_in");
}
...
?>
thebitman at attbi dot com
16-Dec-2002 08:01
[Editor's Note] Locking a session to an IP address will sometimes result in valid user's sessions not being restored. ISPS sometimes use more than one proxy server, the ISP may direct the traffic through a different proxy on each request[/Note]
The easiest (and therefor, most vulnerable) method of validating a session is to just keep a copy of the REMOTE_IP in $_SESSION, and compare it at the beginning of your script. Of course this doesnt prevent someone from blindly sending things to your server and getting no reply, but I think it will do a pretty good job of preventing someone from hijacking your session in order to get ahold of an order confirmation page that has your address and CC# on it.
As a general rule: Keep track of your users. NEVER allow POST data for things like online purchases without making sure that the last page they were on is the page that should be making that POST (and I dont mean checking the referer: header. This kind of thing is what the _SESSION variable can be good for storing)
Jester at free2code dot net
17-Nov-2002 10:50
It seems quite a lot of people have trouble understanding what sessions do and what they're good for.
For a more newbie explanation our tutorial might help you:
I tried to expplain how to use sessions in as simple terms as possible, for anyone having trouble understanding this page, give it a go.
jmgonzal_NOSPAM_at_NOESPAM_netred_DOT_cl
12-Oct-2002 10:43
If you have problem to download a file from your PHP , and you have IE (any version) and apache for server with SSL, check the reference of: session-cache-limiter
My best solution is change the php.ini from
session.cache_limiter = nocache
to:
session.cache_limiter = private, must-revalidate
twocandles3000@hotmail
14-May-2002 06:34
Storing class instances in session.
As long as a class MUST be declared BEFORE the session starts and unserializes the session info, i'm using this approach.
0: Set in php.ini session.auto_start = 0
1: create myclass.inc where the class is declared.
2: put in another file, say header.inc, this lines of code:
include_once( "myclass.inc" );
session_start();
3: set in php.ini the auto_prepend_file= "path_to_my_file/header.inc"
Following this steps, the session is started at every page and myclass is always available, avoiding to write the session_start() function at every page.
stoiev at ig dot com
20-Mar-2002 05:10
Carefull when you are working in PHP with WML. The arg separator used to put de PHPSESSID variable in URL is '&' by default, and this cause a Compile Error in browsers:
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
instead of this:
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
It�s safety include the line:
ini_set ( "arg_separator", "&");
to change the arg separator, it worked in PHP 4.1.2
Another thing that the onpick tag is not defined in the url_rewriter.tags list by default(if there are others, i don�t now). This is must be added in php.ini file.
* In most case the WAP GateWay accepts cookies an the auto-transpass-SID is not necessary, it�s hard to find problems with this.
j dot marloweNOSPAM at gmx dot NO_SPAM dot net
11-Feb-2002 10:47
for anyone in the need of a simple login script tutorial featuring sessions, try here:
ricmarques at spamcop dot net
16-Oct-2000 12:16
Regarding session.cache_limiter :
For those of you who - like me - had trouble finding the meaning of the possible values (nocache, public and private), here's the explaination taken from the HTTP 1.1 Specification at
"14.9.1 What is Cachable
[snip]
public
Indicates that the response is cachable by any cache, even if it would normally be non-cachable or cachable only within a non-shared cache. (See also Authorization, section 14.8, for additional details.)
private
Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache. This allows an origin server to state that the specified parts of the response are intended for only one user and are not a valid response for requests by other users. A private (non-shared) cache may cache the response.
Note: This usage of the word private only controls where the response may be cached, and cannot ensure the privacy of the message content.
no-cache
Indicates that all or part of the response message MUST NOT be cached anywhere. This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.
Note: Most HTTP/1.0 caches will not recognize or obey this directive."
shanemayer42 at yahoo dot com
20-Aug-2000 02:11
Session Garbage Collection Observation:
It appears that session file garbage collection occurs AFTER the current session is loaded.
This means that:
even if session.gc_maxlifetime = 1 second,
if someone starts a session A and no one starts a session for an hour, that person can reconnect to session A and all of their previous session values will be available (That is, session A will not be cleaned up even though it is older than gc_maxlifetime).
| |