スキップしてメイン コンテンツに移動

投稿

2月, 2012の投稿を表示しています

同一セッションに悩まされ

Internet Explorer も、気がついてみたらFirefoxまでも、複数タブ・ウィンドウ間で同一セッションになってしまった。確か、Firefox 3.6のときは、ウィンドウが別だったらセッションも別になっていたと思ったのになぁ... で、同一セッションになって困るのは、セッション変数の扱い。 同じフォームを二つのタブやウィンドウで開くと、後から開いた方の値でセッション変数は上書きされてしまう。 これを防ぐには、フォームがはじめて表示されたときにフォームに対して一意の値を生成し、そいつを毎回POSTする。 そして、セッション配列へフォームの値を保存するときは、POSTされた一意の値をセッション配列のkey、保存したいフォームの値をvalueとすればよい。 で、いらなくなったときに、セッション配列の要素をunset()してやればいい。 この考え方は、ワンタイムチケットと同じ。 こっちも参照 してね。 ワンタイムチケットでなくても、例えばログインフォームで一意の値を生成し、そいつをフォーム間で引き回せば、同じことができる。 ただし、ログインフォームで生成した一意の値が仮に悪意の第3者に漏れた場合、何をされるかわからないので、できれば、一定間隔で再生成する仕組みを考えた方がいい。

クロスサイトスクリプティング対策とかいろいろチェック

基本は出力時のエスケープ 外部から取得した値は、出力時に必ずエスケープする。 <?=htmlspecialchars(外部から取得した値, ENT_QUOTES)?> 外部から取得できる値 ポストされた値 URIのパラメタ値 アップロードされたファイルの内容 データベースから取得した値 しかし、URIを指定できる場所へエスケープして出力しても、「javascript:」で始まる文字列はエスケープされないため意味がない。 <?php // この変数 $var へ代入する値が、$_POST や $_GET $var = 'javascript:window.alert("XSS成功")'; ?> <a href="<?=htmlspecialchars($var, ENT_QUOTES)?>">リンク</a> このような場所へは、外部からの取得値を出力してはならない。 また、エスケープが意味をなさない次の場所へは、外部からの取得値を出力してはならない。 <style>ここ</style> <script>ここ</script> 不正なマルチバイト文字対策 外部入力値に不正な文字コード(EUC-JPなのに1バイトだったなど)が含まれていたり、アップロードしたファイルが壊れていて、正しく文字エンコードを判別できないような場合、意図しない動きになる。特に、日本語のようなマルチバイト文字を使う場合は、必ずチェックする。 mb_check_encoding(外部入力値, 'UTF-8'); mb_check_encoding() は、第一引数で指定したバイトストリームが、第二引数で指定する期待した文字エンコーディングとして有効な場合はtrue、無効な場合はfalseを返すので、無効な文字エンコーディングと判断されたときは、(処理にもよるが)強制終了すればいい。 $var = isset($_GET['param1']) ? $_GET['par...