ログイン後にsession_regenerate_id()を実行するだけで十分か?

ログイン後にsession_regenerate_id()を実行するだけで十分か?

忙し過ぎてタイムリーにブログが書けないです。最近セッション管理の問題が一部で話題になっていました。そこの中に以下のような議論がありました。

ログイン後にsession_regenerate_id()を実行すれば外部からのセッションIDを受け入れても安全

確かにログイン後のセッションIDは本来セッションIDが持つべき属性

  •  一意な値であること
  • 第三者に予測不可能であること

を持っています。

しかし、ログイン後にセッションIDを再生成するだけでは不十分な場合は2つ直ぐに思いつきます。

– CSRF(XSRF)防御にセッションID(だけ)を利用している場合
– 外部に出力したデータの改ざん防止にセッションID(だけ)を利用している場合

これらの仕組みはログイン後にのみ利用する機能ではありません。フォーム送信は認証無しで行うことは多いです。ウィザード型の入力フォーム(検証済みの前のページの入力値を次ページに保存する方法が最も柔軟な処理方法)も認証前に使用されます。

私はCSRF(XSRF)防御にはフォームに予測不可な一意なIDを割り当てる方式を、検証済みデータの改ざん防止にはセッションID+マジック文字列(予測できない秘密の文字列)を利用しています。CSRF(XSRF)対策には影響ないですし、セッションIDを利用してセキュリティを維持する仕組みであっても必ずマジック文字列を使用しているので危険な状態にはなりません。しかし、全てのアプリケーションがこのような対策を取っているとは思えないので外部からのセッションIDを受け付けない厳格なセッションID管理を導入するのはセキュリティ上意味があります。

ほとんどのアプリケーションはログイン後にsession_regenerat_id()を実行するだけで十分な安全性を確保することが可能ですが一部のアプリケーションはそれでは不十分であることは知っておいたほうが良いと思います。

追記:2001年からウィザード型フォームで前のページのデータを安全に保存するため等に利用できる関数をZendのコードギャラリに載せています。ウィザード型フォームはこのような関数を使用し検証済みの値のメッセージダイジェストを取っておけと繰り返し入力値を検証する必要性がなくなります。

Google Source Code Bug Finder

Google Source Codeで自動的にバグ(らしきもの)を見つけるページ

http://www.cipher.org.uk/projects/bugle/BugleAutomated.php

古いコードも一緒に検索されたりしますが「Package Name」オープンソースのプロジェクト名(ソースのtar玉のパッケージ名の部分など)を入力すると自動で怪しいコード見つけてきてくれます。

htmlspecialcharsは脆弱

追記:現在のPHPでは問題ありません。パフォーマンスを考えるとhtmlspecialchars()の利用をお勧めします。新しいエントリを参照してください。

PHPのHTMLエスケープ

PHPにはHTMLの文字列として出力する関数が2種類あります。

  • htmlspecialchars() <,>,&,’,”等のHTML特殊文字をエンティティ化する
  • htmlentities() HTMLエンティティ化が必要な文字全てをエンティティ化する

あまり脆弱性に関係なさそうですが文字エンコーディングとの組み合わせで攻撃に利用される可能性があります。このようなシナリオです。BBSやブログのコメントなどユーザが送信したデータをHTMLページの一部として表示するアプリケーションがあるとします。

  • ワザとアプリケーションが期待している文字エンコーディングと異なる文字エンコーディングでデータを送信し、その中にJavaScriptを実行可能なデータを入れる
  • データが保存されページが表示された際には異なる文字エンコーディングのデータが表示され文字化けする。

通常、文字化けしたページが表示されるにとどまる場合が多いと思われますが以下の状況が考えられます。

  • 文字エンコーディングが指定されていない場合、ブラウザが文字エンコーディングを自動判別し本来の文字エンコーディングとは異なる文字エンコーディングが利用されていると判断しJavaScriptが実行される。
  • ユーザが文字化けしたコンテンツを参照するために「明示的」に文字エンコーディングを変更し、その際にJavaScriptが実行される

htmlspecialcharではISO-2022-JPのマルチバイトスタート文字列などはエンティティ変換されないため意図した文字エンコーディング以外でページが表示された場合、JavaScriptが実行される可能性があります。htmlentitiesで変換していれば指定された文字エンコーディング以外のデータはエンティティ変換されます。このため意図した文字エンコーディング以外の文字エンコーディングでページが表示されてもJavaScriptが実行されることはありません。

本来、すべてのアプリケーションはユーザからの入力等が正しい文字エンコーディングがあるかチェックし不正なエンコーディングが含まれている場合はエラーとして処理を停止すべきです。このように正しく入力をチェックしている場合はhtmlspcialcharsを利用していても問題が発生する事はありませんが、このチェックが無い場合はhtmlentitiesを使用していないとJavaScriptインジェクション(XSS)に対して脆弱になります。

UTF-7エンコードされたタグ文字列によるXSS脆弱性に注意
http://slashdot.jp/security/article.pl?sid=05/12/21/2318216

これはUTF-7を使用した例です。scriptタグを隠すSJIS、EUC-JP、ISO-2022-JP等を利用した攻撃例も知られています。

RavMonE.exe付きVideo iPod

なんとなくMacつながりでウィルス付きMP3プレイヤーの次はウィルス付き(RavMonE.exeは感染型Adwareだそうです)Video iPodが出荷されていたそうです。

http://www.wagang.jp/blog/logdata/eid64.html によると

RavMonE.exeウイルス。こいつに感染すると、リムーバブルディスクのアイコンがダブルクリックで開かなくなり、アクセス速度が遅くなったりします。実害はそれだけ。でも、凄くウザイ。
で、これがまたヘンなウイルスみたいですねえ。このページでは、传染性杀毒软件、すなわち「伝染性アンチウイルスソフト」と称しています。なんでも、中国国産アンチウイルスソフト、瑞星殺毒の自動監視をONにしてると、リムーバブルディスクが監視対象になってRavMonE.exeが自動でコピーされ、ダブルクリック時にエクスプローラを開かずにRavMonE.exeを実行するようにレジストリが書き換えられる、そのEXEファイルと設定が、当該リムバディスクを繋いだ他のパソコンにも連鎖的にコピーされていく、ってことみたいです。

と記述されています。アンチウィルスソフト(瑞星殺毒)の自動監視機能で感染?というのはよく分からないですがミイラ取りがミイラになった、ということなのでしょう。RavMonE.exeでぐぐると中国語のサイトがかなりヒットします。Appleの書き方だと「こんなウィルスに脆弱なWindowsが悪い」などと書いているので瑞星殺毒の自動監視をONにしていなくても感染するようにも思えます。いずれにせよ実行すれば同じことなのでRavMonE.exeがiPodに入っていたら実行しないことが重要と思います。信頼できると思われる製品にexeファイルが入っていたら普通、実行してしまうとは思いますが..

We recently discovered that a small number – less than 1% – of the Video iPods available for purchase after September 12, 2006, left our contract manufacturer carrying the Windows RavMonE.exe virus.

2006年9月12日以降に購入したVideo iPodに影響があるようです。どこの地域に出荷されたiPodが対象になるのか分かっていれば記載した方が親切と思います。誰かが意図的に添付したのか事故で入ったのかどうなのか分かりませんが一般的なアンチウィルスソフト(Norton AntiVirus、McAfeeなど)で検出&修復できるようです。iPod nano and iPod shuffle には影響ないようです。

we are upset at Windows for not being more hardy against such viruses

一応ウィルスを検出できなかった自分たちにも腹が立つがこのようなウィルスに簡単に感染するようなWindowsに腹が立っているのだそうです。この一文は余計なお世話なような.. Apple製のソフトウェアにも脆弱性はありますから。しかも、自動感染するのは瑞星殺毒の脆弱性のようにも読み取れるのですがどうなんでしょう?

http://www.wagang.jp/blog/logdata/eid64.html には

当該リムバディスクを繋いだ他のパソコンにも連鎖的にコピーされていく

とあるのでやはり一旦感染するとどんどん感染していくのでしょうか?だとすると「瑞星殺毒の自動監視をON」しているかどうか関係なく「Windowsの脆弱性」が問題となると思います。未修正のWindowsの脆弱性が原因なら、同じ脆弱性を利用した未知のマルウェアが無いとも限りません。他人のUSBメモリをさすのは非常に危険ということになります。実際のところはどうなのか気になるところです。
# 中国語が読めればもう少し情報が得られそうですが読めません。

  • 「瑞星殺毒の自動監視をON」-> 自動実行設定なしにRavMonE.exeに感染
  • RavMonE.exeに感染したPCは接続されたメモリ等に自動実行設定行う -> Windowsの自動実行機能によりRavMonE.exeに感染

となって自動実行機能の問題ということかな?読み込み専用メディアでさえ自動実行機能のリスクは高く自分が使うPCはこの機能をOFFにしています。もしかして書き換え可能なメディアでもautorun.infを使うと自動実行できると言う事?(時間もないので試してません。もしそうだとしたらかなり悪い仕様ですね..「we are upset at Windows」と言うのも理解できる.. 時間ができたら試してみよう)

F-SECUREのブログでこの問題に気が付いたのですがここで検索してみてもRavMonE.exeでは情報は見つかりませんでした。他のサイトによると7月くらいには見つかったマルウェアらしいのでメジャーなアンチウィルスソフトには入っているようです。探し方が悪かったのかSymantecのサイトでも何も見つかりませんでした。

追記:USB接続したメディア内の“autorun.inf”を自動実行できる「APO Usb autorun」の様なユーティリティがあるのですね。やはりデフォルトでUSBメモリ内のautorun.infを実行するような馬鹿な事はしていなかったようです。であれば別の方法で感染するということなのか、単純にEXEファイルだけをコピーするのかどちらなんでしょう。
http://prism-project.sakura.ne.jp/usb_memory/usbmmain2.html によると

上の表の通りUSBメモリでは自動実行ファイルであるautorun.infを入れた場合アイコンの変更はできてもファイルの実行はできないという事です。従ってUSBメモリにランチャー等を入れてautorun.infで実行ファイルに指定してもランチャーは自動起動せず動作の選択画面が出るという事です。

とあります。当然の仕様だと思います。USBメモリをさすと勝手にプログラムが実行されるようでは昔のFDDのブートセクタウィルス状態になります。iPodの件はPCがRavMonE.exeに感染しiPodを検査した際に勝手にコピーされたということだったと思われます。Windowsの脆弱性ではなくアンチウィルスソフトの脆弱性で自動感染するようなので「we are upset at Windows」の意味がよく分からない.. MacOS Xの場合はソフトをインストール場合に管理者パスワードが要求されることがありますが、Windowsでは普通は「管理者権限」を持つアカウントでないと「使えない」情況にあることを指して「we are upset at Windows」ということなのかも知れません。ネットにはUSBの場合でも自動実行できてしまう(USBでも自動再生機能で再生するアプリケーションは選択できますが自動でプログラムは実行できない模様。自動実行と自動再生には大きな違いがあります)と勘違いして記載されているページもあるようです。これが「we are upset at Windows」の理由なのかも?!

ちなみに自動再生機能を無効にするにはSHIFTキーを押しながらドライブを開きます。Tweak UIにも自動再生の設定項目があります。

サポート期限切れの製品 – Webサイトで警告を出すのが良いかも?

今月のWindows UpdateでWindows XP SP1用の最後のアップデートだったそうです。SP2にしないとパッチ無しになります。Windows XP SP2以上でないとインターネットに接続してはならないPCということになります。(Windows 95/98/ME等は問題外)大多数のユーザはSP2にしているとは思います。しかし、古いOSやアプリケーションをそのまま使い続けている方も多くいるはずでそういったPCがボット化していくのだと思うと困ったものです。

このブログの場合、

  • Windows利用者の中でWindows 95/98/Meを利用されている方は約1%
  • IEでアクセスされている方の約1%がIE5.x以下ブラウザを利用(IE5.x以下は全てサポート期限が切れています)
  • Firefoxでもセキュリティホールがある古いバージョンを利用されている方が5%程

といった感じです。(Google Analyticsの統計情報より)
# ブラウザ全体の内訳はおおよそIE64%、FF28%、その他ブラウザ8%です。
# 一般的サイトに比べるとかなりFF、その他ブラウザが多いです。

そこで「このサイトを見るにはIE5.5以上、Firefox1.0以上で快適にご覧いただけます」と記述しているページを設けているサイトは多いです。少なくともこのページに「20XX年X月XX日時点の情報によると、あなたのOS(ユーザのOSとバージョン)、ブラウザ(ユーザのブラウザとバージョン)には既知の脆弱性があります。早急にアップグレードお勧めします」と記載してはどうでしょうか?メーカーの問い合わせ先URLなどを記載していてもサイトに問い合わせするユーザがいて困るかも知れないので尻込みしそうですが、こうすれば少しはアップグレードのモチベーションが上がるかもしれません。

以下のページにWindows関連のサポート期限がまとめられています。
http://www.st.ryukoku.ac.jp/~kjm/ms-windows/support.html

エンドユーザは意外にこういった情報を知りません。本来はメーカーのホームページの簡単にアクセスできるところにこういった情報が載っているべきと思います。

IE7は自動更新

ついに最終版IE7 (RC1)がリリースだそうです。もしかしたらRC2くらいまでは出るのかも知れませんが、IEブログを見ると今月には出るよと書いてもあります。RC1で特に大問題が無ければリリースするつもりなのでしょう。特にコンポーネントとして使っていたりActiveXを使っているユーザは動作検証の必要性が高いと思います。

IE7ダウンロード:
http://www.microsoft.com/japan/windows/ie/downloads/default.mspx
IE7概要:
http://www.microsoft.com/japan/windows/ie/ie7/about/default.mspx

IE7タブ一覧
タブがこのように一覧できるのは便利です。このイメージでは分かりませんが英文字だけアンチエイリアスがかかっていてぼけて見えるのは好きになれません。個人的にはアンチエイリアスがかかり過ぎたテキストは非常に読みづらく感じます。

正式版は自動更新となるらしいのでかなり数のユーザがIE7に乗り換える事になります。いっそのこと「IE7しかサポートしません。全ユーザ乗り換えてね」の方がありがたい…

ときどき見かけるのですがセッション変数にフォーム状態を記録しているアプリケーションがあります。フォーム状態をセッション変数として保存すると同時にページを開いた作業が行えなくなったり、おかしな状態になったりします。Webアプリケーションとして「同時に1ページしか開かない」といった前提は設けるべきでないでしょう。IE7はタブブラウザなのでこのようなWebアプリケーションは修正が必要になってくると思います。
# 複数のIEを立ち上げれば同じことですがマルチタスク(死語ですね)を
# 無視したアプリケーション設計の典型的な例です。そういうサイトでは
# WCAGで「使わないように」と言われている「新規ウィンドウでリンクを
# 開く」機能を頻繁に使っていたりします。矛盾しているとは思わない
# ませんか?

不適切なアプリケーション設計と言えばブラウザの「戻るボタン」を利用できないWebアプリケーションも比較的頻繁に見かけます。ウィザード型のインターフェースを持つフォーム状態を維持するためにアプリケーションの戻るボタンを利用しないとエラーになるWebアプリケーションがあります。CSRF対策の意味もあるのかも知れませんが、ブラウザの戻るボタン機能を無効にする対策が優れているとは思えません。不必要に利便性を義性にしている(ブラウザの戻るを押しら前の入力が全て無効になる)と言われても仕方ないと思います。CSRF対策なら別の方法を利用すべきですし、戻るボタンを押されたら前に入力されたデータの完全性が保証できないのであれば手抜きをしているか不適切なアプリケーション設計が原因と思われます。この手のサイトは「同時に1ページしか開かない」を前提にしている事も多いのでついでにこれらの不適切な設計も直してほしいです。私もチケット予約に利用している某サイトはこの手のサイトです… そして2回に1回はマウスの戻るボタンを押してやり直しているような気がします。

タブブラウザが当たり前になることで「1クライアント=1ページ」を前提とすることは非常識な設計になれば良いと思います。ついでにブラウザの「戻るボタン」が使えないサイトも非常識な設計になれば助かります。

新しいWiki – QEDWiki

リンクをクリックするとデモが見れます。久しぶりにZendFrameworkのホームページを見てこのデモがある事に気が付きました。

IBMの方がZendFrameworkを利用して作っているらしいです。AJAXはもちろんですが、Wikiコマンドと言うシンプルな言語でいろいろ拡張できるようになっている様です。ドラッグアンドドロップで設定するGoogleマップと天気予報の連携のデモがあります。UIのほとんどはDojoを使っているのだと思われます。(ソースか実物を見ないと分かりませんが)

確かに便利そうにも見えますがWikiコマンドには括弧が多すぎな気もします。Lisp好きな方がデザインしたのかも知れませんね。

PostgreSQL 8.2 Beta

PostgreSQL 8.2のリリースノートは非常に長いのですがアプリケーションプログラマのコーディングスタイルに大きく影響するのは次の変更(追加)だと思います。

Add INSERT/UPDATE/DELETE RETURNING (Jonah Harris, Tom)

This allows these commands to return values, such as the computed serial key for a new row. In the UPDATE case, values from the updated version of the row are returned.

MySQL等で挿入後のID番号が取得できる機能がPostgreSQLでも作れるようになりました。

create table test (
id serial,
msg text,

primary(id)
)

としてidフィールドの値が何になったのか分からないと困る場合が多かったので

create table test (
id int8,
msg text,

primary(id)
)

としてsequenceの次の値を取得してidにセットしていたと思います。今後はより気軽に

INSERT INTO test(msg) VALUES (‘abc’) RETURNING *;

として挿入後のデータが参照できるようです。
Ruleやストアドプロシージャでデータを加工している場合にも便利ですね。

PostgreSQLの場合、6.xのころからRuleを使うと比較的簡単に全ての変更をログできるのですが、この機能を使えばアプリケーション側でデータのログを取るコードが簡略化できます。データベースレベルではアプリケーションを操作しているユーザIDが分からない場合が多いので便利になります。

PostgreSQLに関する間違い情報

PostgreSQL 8.0は2005年1月にリリースされました。SAVEPOINTは8.0からサポートされている機能ですが、2006年4月の記事で「サポートしていない」と間違った情報が記載されているページを見つけました。

 ロールバックはトランザクションの開始処理まで戻るのが基本であるが,「セーブポイント」機能を利用すれば部分的な処理の取り消しが可能になる。図4[拡大表示]上に示したようにトランザクションの中に「SAVEPOINT(セーブポイント名)」を設定し,「ROLLBACK TO(セーブポイント名)」とすれば,ROLLBACKからSAVEPOINT間の処理を取り消すことができる。1つのトランザクションには複数のセーブポイントが設定可能である。セーブポイント機能はOracleにはあるがPostgreSQLには無い

しかし、よく見ると

出典:日経オープンシステム 2003年2月号 142ページより
(記事は執筆時の情報に基づいており,現在では異なる場合があります)

とあり書いた時点では正しい情報です。3年も経つとかなり変わりますから技術記事の再利用は難しいですね。この記事は新人対象のようですがこれを読むとそのまま信じてしまいそうです。

RSSリーダへのインジェクション

少し前にセキュリティ系のMLに「RSSにインジェクション」と言う話題があったのですが実際に調べるとインジェクション出来てしまう物が結構あるようですね。全て使った事が無いものばかりですが

– Ykoon RssReader CVE-2006-4762
– SharpReader CVE-2006-4761
– RSSOwl CVE-2006-4760

等があるようです…

RSSOwlはJavaアプリケーションのようですね。リンクをクリックしてブラウザを立ち上げるとJavaScriptが実行されて… と言った攻撃方法なので信頼できるサイトのフィードなら大丈夫ですが、MLやブログコメント等のフィードは危険性が高くなります。

ところで、Firefox, Thunderbirdのアップグレードでてますね。

MFSA 2006-64 Crashes with evidence of memory corruption (rv:1.8.0.7)
MFSA 2006-62 Popup-blocker cross-site scripting (XSS)
MFSA 2006-61 Frame spoofing using document.open()
MFSA 2006-60 RSA Signature Forgery
MFSA 2006-59 Concurrency-related vulnerability
MFSA 2006-58 Auto-Update compromise through DNS and SSL spoofing
MFSA 2006-57 JavaScript Regular Expression Heap Corruption

ブラウザ関係ではFlashplayerのクリティカルなアップデートも出ています。私はこれを機会にWindowsはFlash Player9にしました。
# Linux、Solaris用のFlash Player 7はアップグレード版があるようですね。
# Zero3 esのFlash Player 7などはどうしろと言うこと…

Flash Player 8 update (8.0.33.0), and Flash Player 7 update (7.0.66.0 or 7.0.68.0) address security vulnerabilities in previous versions of Flash Player. Updated versions of Flash Player 7 for Linux and Solaris, which contain fixes for these vulnerabilities, are also available from the Adobe Player Download Center.

http://www.adobe.com/support/security/bulletins/apsb06-11.html

PEAR DBのPostgreSQLドライバにセキュリティホール

この脆弱性は本家にはレポートしてあるのですが簡単な1行パッチなのにまだCVSにさえ適用されていません。詳しく解説したつもりなのですがシングルバイト圏の開発者には理解が難しい(?)か私の説明が悪かった(?)のかも知れません。とりあえず「作業中」との旨のメールが帰って来ていますが遅すぎなので特に影響が大きいと思われる日本のサイト向けとして問題の概要と対処方法を書いておきます。

文字エンコーディングを利用したSQLインジェクションに詳しい方ならどのような条件でSQLインジェクションが可能になるか簡単に分かります。addslashesやstr_replaceによるエスケープが危険であることは広く知られている既知の問題といえると思います。英語で記述されたブログ等にもエンコーディングとエスケープの問題を取り扱ってるページもあります。あまり長期間放置していると近い将来悪用される危険性があります。

このパッチを有効に利用するには使用しているPostgreSQLサーバのバージョンに関わらず、PostgreSQL 8.1.4以降のlibpqを利用してPHPのPostgreSQLモジュールをビルドする必要があります。
# これはPostgreSQL 8.1.4以降のlibpqを利用しなければならいない
# 点はPEAR DB/PHPに限らず、PostgreSQLアプリケーション全般として
# いえます。

[yohgaki@dev pear]$ cat DB/DB/DB_pgsql.php.patch
Index: pgsql.php
===================================================================
RCS file: /repository/pear/DB/DB/pgsql.php,v
retrieving revision 1.129
diff -u -r1.129 pgsql.php
— pgsql.php 10 Jun 2005 14:31:45 -0000 1.129
+++ pgsql.php 17 Aug 2006 09:34:16 -0000
@@ -531,7 +531,7 @@
*/
function escapeSimple($str)
{
– return str_replace(“‘”, “””, str_replace(‘\\’, ‘\\\\’, $str));
+ return pg_escape_string($str);
}

// }}}

他のDBアクセス抽象化ライブラリにも同じ脆弱性がある可能性が高いと思われます。パッチ自体は簡単なのでDBアクセスアクセスの抽象化ライブラリを利用されている方は一度調べた方が良いと思います。

「はじめてPHP言語プログラミング」に新しいコメント

本書はPHPプログラミング「入門」と銘打っている。しかし、たとえば値渡し・参照渡しといった重要事項が、ごく簡単にしか説明されていない。これでは、全くのプログラミングの素人にはきついのではないか。逆に、CやPerlなどをかじったことがある人であれば、簡潔でいいのかもしれないが…。

また、具体的な関数・メソッドの索引はほとんど省かれている。だから、実際にプログラムを書くためには、他のマニュアルで確認する必要がある。とはいえ、公式サイトのマニュアルが日本語版も充実しているからそれを読めばいいのだが、巻末の索引だけで事足りないのは不満。

技術書には

– チュートリアル
– リファレンス
– 解説書

の3種類があると考えています。私としては「入門書 != チュートリアル」「入門書 != リファレンス」であり基本的には「入門書 == 解説書」だと思っています。

もちろん手取り足取りのチュートリアル型の入門書を否定するつもりはありません。チュートリアルが必要・好みの方はそのタイプの入門書を購入されれば良いと思います。執筆時点でチュートリアル型のPHP入門書は多数出版されていたので多少硬派なPHP入門書(解説書)として書いてみようと思って執筆しています。このコメントにあるように既にプログラミングを知っている方に読みやすい、分かりやすいを狙っていたのも確かです。

参照渡しと値渡しの解説が初心者には不十分とあります。自分でもどう書いたのか忘れたので後で見てみることにします。リファレンスとして利用できるようになっていた方が便利なのは分かります。この点は考慮した方がよさそうです。

書名に「はじめて」と書いてあるのでプログラミング初心者向けのチュートリアル型の入門書でないと「期待と違う」と言うことになってしまうのでしょうね… この本の「はじめて」ははじめて言語としてPHPを解説した本、という意味をこめて付いているのですが誤解を招いてるのでしょう。書名は大切ですね。

あとAmazonの評価を見ると「減点方式」で評価している方が多いようです。とりあえず「満遍なく」が良いようです。「はじめてのPHP言語プログラミング」のコメントはどれも非常に参考になりました。これから執筆予定のZend Framework+Prototypeの入門書の執筆の参考にさせて頂くつもりです。

Webアプリセキュリティ対策入門」には評価が付いていないです。このブログでもAmazonでも構わないのでご意見を頂ければ参考にさせて頂きます。

マカフィー製品のインストールとアンインストール

McAfeeのインターネットセキュリティスイート2006を使ってみました。この製品はマイクロソフトのみ環境でのみの利用を想定しているのか、デフォルトブラウザがFirefoxだとインストール後のダウンロードで問題が発生しました。プライバシーを保護するプログラムが中途半端な状態になり、削除もアンインストールもできない状態になりました。

# しかもこのプライバシー保護用のプログラムは重すぎです。
# 結局重すぎで使えないプログラムなのでインストールしてい
# ません。あまりにCPUを使うので最初はマルウェアのプロセス
# かと思いました。

更新用のプログラムがIE6を使うようになっているのでIEがデフォルトでなければならないようです。私のLinux/WindowsのFF1.5ではサポートページのレイアウトが崩れているのでデフォルトブラウザがIE以外に設定されているのは想定外??

更新用プログラムを今時わざわざIEのActiveXとして動作させるプログラムにしてくても…と思います。しかも「セキュリティで保護されていないコンテンツ含まれています」と毎回表示される画面もあります。

とにかく困ったのはFFがデフォルトブラウザだったせい(?)で中途半端にインストールされたので、インストールも再インストールもアンインストールできなくなったことです。マカフィーのサイトにテクニカルサポートのFAQがあるのですが、インターネットセキュリティスイート2006のインストール・アンインストールは

http://www.mcafee.com/Japan/mcafee/faq/ssi_answerCSAllProducts.asp?ancQno=AP-00003&ancProd=AllProducts&ancExQNo=IS-00003&ancExProd=InternetSecurity&ancExVersion=:6%20:2005%20:2006

だけのようでした。当然ですがこのページ書いてあるようなことは既にやっています。全く役に立ちません。散々苦労してやっと

マカフィー製品を完全に削除するツール
http://www.mcafee.com/Japan/mcafee/faq/howtodownload.asp

を見つけコレで全部削除できました。一旦動作すると予告なしに勝手に再起動するので注意が必要です。再起動後にログインすると自動的に削除を再開します。セーフモードで実行すると再起動無しに全て削除できるようです。

このページの日付は2004年と日付が古いですがインターネットスイート2006でも使えるようです。きっとインターネットスイート2006ではサポート対象外なのでしょうけどFAQの分かりやすい場所に載せておいてほしいですね。マカフィー製品で困ったことになった方は上記の削除ツールを試してみると良いと思います。

Zend FrameworkのZend_Db

このブログでZend Frameworkの事はほとんど書いていませんが、セキュリティ関係のところを少しだけ書きます。

Zend Frameworkはまだまだ作りかけ、と開発元が言っているだけあって、セキュリティに関係する部分も作りかけだったりします。

例えば、mysqliアダプタは適切にエスケープ処理されていますが、Oracleアダプタのエスケープ処理は全く行われていません。DB2のアダプタの場合、”でくくられるべき所がくくられていなかったりします。

Zend Frameworkとは関係ありませんが、PostgreSQLのPDOドライバは出来が悪いので事実上PostgreSQLでZend_Dbは使えません。
# 一見使えるように見えますがメモリ管理に問題がある
# らしく、はまる可能性があります。

PHPカンファレンスで「Zend Frameworkを使っている方?」と聞かれて、手を上げたのは私の他数名だったので大丈夫とは思いますが、実際のシステムに使うにはコードをよく読んでから使わないと思わない落とし穴にはまる事になります。

秋の1.0リリースかリリース候補では修正されていると思いますが、今のところこんな感じです。

PostgreSQLのプリペアードクエリとUnitテスト

PostgreSQLのプリペアードクエリを使ったプログラムのユニットテストを書いてユニットテストの書き方の問題に気がつきました。普通にユニットテストを書くと

relation with OID ##### does not exist

というPL/PgSQLで良く見かけるエラーが発生してしまう場合があります。

通常ユニットテストを書く場合、テストのセットアップ関数(メソッド)で

create table test (a text, i int);

テスト終了時に

drop table test;

と書きます。

プリペアードクエリの場合、コンパイルされたSQL文がバックエンドにキャッシュされるので「Web環境などで永続的な接続」を行っている環境でこの様な初期化、終了ルーチンを持つユニットテストでPostgreSQLのプリペアードクエリを実行するテストを「2回以上」行うと

relation with OID ##### does not exist

とエラーが表示されてしまいます。キャッシュされた(プリペアされた)SQL文に対応するテーブルが削除されてしまった後もクエリはキャッシュされているので削除されたの存在しないテーブルアクセスしようとしているので上記のエラーがでます。
# プリペアされたクエリは名前でなくOIDでテーブルにアクセスするので
# このエラーが発生します。

コマンドラインからのユニットテストの場合、接続の種類は影響しませんがPHPでWebサーバ上でユニットテストを実行する場合、pg_prepare, pg_execute を使ったプログラムのユニットテストにはpg_connectを使うほうが良いです。pg_connectを使っていても同じ接続を使っている間にテーブルの削除/作成を行ってもpg_pconnectを使っている場合と同じ理由でこのエラーが発生します。コマンドラインでもすべてのテストを実行するスクリプトを利用している場合は注意が必要だと思います。PL/PgSQLのエラーが何故発生するのか理解していれば直ぐに原因に気が付くと思いますが、そうでなければなかなか気が付かないかもしれません。

私も最初は何の事だか解らずググってもPL/PgSQLのエラーに関連するページが表示されていました。pg_prepare/pg_executeについては少なくとも上位には表示されなかったので書いておきます。

PostgreSQLのプリペアードクエリの実装(と言うか実際にOID参照しているもの)を詳しく調べてから書いていないので「実装と違う」という場合は是非指摘してください。

# Javaのユニットテストでこの問題が発生する、というページ
# も無かったような気がします。当り前すぎ(FAQ)だから?

# 問題を回避するもう別の方法にDEALLOCATEを使ってプリペアされた
# SQL文を削除しておく方法もあります。削除するのは面倒ですがこちら
# の方法ならどのような環境でも困らないと思います。