年: 2006年

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文を削除しておく方法もあります。削除するのは面倒ですがこちら
# の方法ならどのような環境でも困らないと思います。

IEEEのセキュリティサイト

A Process for Performing Security Code Reviewsのような記事が公開されています。The State of Web Security等は何かプレゼンテーションを作る場合に役立ちそうです。

基本的にはブログのようになっているようです。しかし、ここの記事は時間が経つと買わないとならない(?)ようです。画面上部の”Contents”リンクをクリックすると有料コンテンツのリストが表示されます。Process for Performing Security Code Reviewsは$19だそうです。Adsenseでも何でも良いので広告を付けて無料にしてくれればありがたいのですが。# 日本語で書いていても何の効果もないでしょうけど。

リモートファイルの読み込みが可能なPHPアプリ多数

PHPには

require(‘http://example.com/script.php’);

と外部のURLからデータを読み取りローカルのスクリプトとして実行する機能があります。以下のようなスクリプトが致命的であることは以前にも書きました。

require($_REQUEST[‘type’].’.php’);

allow_url_fopen設定で読み取りの可否を変更できるようになっているのですが、ストリームのphp://inputは制限できないので、allow_url_fopenの設定に関わらずリモートスクリプトが実行できてしまう仕組みになっています。(「php://inputによりPHPスクリプトインジェクションが可能になる」とした方がより正しいですね)

最近、この不正なリモートスクリプトの読み取り・実行が行える脆弱性を調べている方がいるらしくCVEに何十ものリモートスクリプト実行脆弱性のエントリが作られています。見かけた事があるアプリケーション名にはmanbo、horde等があります。当たり前ですが利用中しているアプリのリリース情報はこまめに調べないと危ないです。

# しかし、こんなにたくさんリモートファイル実行
# に脆弱なアプリが在るとは….
# shopなんとかとか、cartなんとか、と明らか(?)に
# EC系のアプリにも問題が多く在るようです….

とは言っても

Successful exploitation requires that “register_globals” is enabled.

となっている物も多いようです。共有サーバなどではregister_globals=onのサイトもまだまだ多いでのしょう。スクリプトを公開する場合、

if (ini_get('register_globals')) {
  die('Turn off register_globals for security reasons');
} 

などを必ず入れておいた方が良いようです。

やはり難しいのかも?!

タイトルどおり「書かない日記」なっているので久しぶりに書きます。

先日のPHPカンファレンスで私のセッションを聞かれた方は「一応、問題はレポートしてあります」と話していた件、と言えば覚えていらっしゃると思います。この件、返信メールが来ていました。他のシングルバイト圏の方と話したときと同じかなと思いました。「これって問題なの?」と言う内容のメールでした。とりあえず「コミットしておいてください」と返信しておきましたがどうなることやら… 日本の開発者でも最初は「??」と思われる方も多いので仕方無いのでしょう。 

PHPカンファレンスの私のセッションのプレゼンテーションファイルをご希望の方、メールをください。このプレゼンテーションファイルは個人的に使うか出所が分からないように一部のみ使って頂けるようお願いします。

“unable to scan $HOME/Maildir”

ohgaki.netのメールサーバにはqmailを使っているのですが、 また”unable to scan $HOME/Maildir”とpop3d がエラーで終了してしまいました。

このエラーはエラーメッセージの通りMaildirをスキャンできないため表示されるエラーです。qmailのpop3dがMaildirをスキャンしている途中に何らかのエラーでスキャンに失敗した場合に表示されます。私が知る限りでは2種類の原因があります。

1. Maildirへのディレクトリへのアクセス権限の問題。(ユーザがMaildirを所有していないなど。Virtualホストの場合はVirtualホスト管理アカウント以外の所有になっているなど)
2. pop3dのrunスクリプトでsoftlimit(利用可能なメモリを制限するコマンド)を利用しているとpop3dがその制限を越えてメモリを利用しようとした場合。

今回の場合、普通に使えていたpop3dが突然特定のアカウントだけで利用できなくなったので2のケースかな?と思い10MB余分にメモリを使えるようにしたらエラーが無くなりました。前に同じ原因でエラーが起きたのを覚えていたので良かったのですが、次は忘れているかもしれないのでメモとしてブログに残しておきます。

MLの宛先にユーザのメールアドレスを使用しない方が良い?

ディスカッションを行うMLを除き「MLのTo:(宛先)に送信先のユーザメールアドレス(各個人のメールアドレス)を記載するのは迷惑だ」と思っていました。理由は次の通りです。

– MLの情報は私信ではない。したがってTo:である必要はない。
– To: に自分のメールアドレスが入っている場合には特別なフィルタ処理行っているユーザが多いと思われる。

商用サイトのMLなどはTo:に設定されている特別なフィルタ処理を考慮して、ユーザがメールを読んでくれやすいよう「確信犯」でTo:に送信先メールアドレスを記載していると思います。

確かに昔はTo:に送信先に個人のメールアドレスアドレスを使っていると読まれる確立が高くなり、商用MLの送信者にはある程度のメリットがあったと思います。しかし、最近はSPAMが多くなりすぎていてデメリットの方が多いのではないかと思います。

例えば、私の場合フィルタルールでTo:かCc:に自分のメールアドレスが記載されている場合、特別なフォルダに保存されて分かるように分類しています。しかし、詐欺・迷惑メールは一部の商用MLと同じくTo:に自分のメールアドレスを記載して送信してきます。MLのメールも詐欺・迷惑メールも送信先のユーザに読んでほしいので同じ事をしてきます。その結果、私の個人アドレス宛のメールフォルダには詐欺・迷惑メールと振り分け処理を行っていないMLのメールが保存されます。

詐欺・迷惑メールの多くはSPAMフィルタでほとんど削除されますが、量が多すぎて一部はフォルダに残ってしまいます。MLのメールも残っているのですが、MLのタイトルと迷惑メールのタイトルはたいして違いが無い場合も多いので間違ってMLのメールをSPAMメールとマークしてしまう場合があります。(AmazonのメールとかSPAMになっていてキャンペーンのクーポンメールがゴミ箱に行きかけたことも…)一旦、迷惑メールと判定してしまうとかなりの確立で同じMLからのメッセージは迷惑メールとして処理されてしまう事になります。これでは、「ユーザに読んでほしいからTo:にユーザの個人メールアドレスを設定する」意味が無いと思います。

確かに私信に近いカスタマイズされたML(というよりはダイレクトEメール)も多いですが、customers@example.comの様なアドレスを使い、タイトルのプレフィックスにサイト名を書いて「example.com: あなたにお勧めの10冊!」等と書いた方がスパムに分類される確率が低くなると思います。特にユーザが「迷惑だ」と思っていない場合には効果が高いと思います。

まっとうなMLは宛先にユーザのメールアドレスを使用しない方が良いように思います。

システムが自動的に送信するメールでも一部のメールにはTo:にcustomers@example.comのようなアドレスは向かない物もあると思いますが、多くの商用MLはTo:に個人メールアドレスを設定する必要は無いように思えます。

良く知られたPHPの脆弱性…

また新しいsafe_modeをバイパスできる脆弱性を利用した攻撃方法を見つけた人がいるようです。safe_modeをバイパスできる脆弱性なので大きな問題とは思いませんが、

CVSS Severity: 7.0 (High)

となっていますね….

具体的には

This issue is due to an input validation error in the “error_log()” function that does not properly validate the destination parameter, which could be exploited by malicious users to bypass the safe mode feature by supplying a “php://” wrapper with directory traversal sequences as a destination argument.

の様なことができてしまう事が問題としてあげられています。

<?php
$file=””; # FILENAME
error_log(“<? echo \”cx\”; ?>”, 3,
“php://../../”.$file);
?>

が攻撃例としてあげられています。最初のアドバイザリメールには6/10にPHP開発者に連絡しレスポンスが無かったと書いてあります。

このようなケースはsefe_modeの範疇外(sefe_modeはfail safeを提供する機能。攻撃から防御する機能ではない)なので無視された、ということだと思います。

ちなみに、セーフモードはPHP6では無くなります。個人的にはfail safe機能としては非常に有用な機能だと思いますが、セキュリティホールとしてレポートされすぎるので削除されます。以前にも書きましたが「なんだかなぁ」と感じます。

システム上のファイルにアクセスしたければデータベース経由や他のライブラリ経由でアクセスすればアクセスし放題なんですけどね… safe mode = sandbox と勘違いしているユーザが多すぎです。

安全と思われていて実は危険なソフトウェア15種 – 宣伝のためのホワイトペーパー

ホワイトペーパーというものは基本的に宣伝の為に作成するものであって「危険なソフトオウェア15種」というホワイトペーパーも宣伝の為のホワイトペーパーでしょうね。PDFのダウンロードには登録が必要らしい(?)のでPDF自体は読んでいません。「危険なソフトがインストールされていないかチェックするにはこちらを見てね」といった旨の記述がPDFにはあるらしいです。

マーケティングではパブリシティーを有効活用するのは重要な事です。このPDFはマーケティング的には、少なくとも日本では、成功していると思います。自社製品の宣伝目的だったとしても有用な注意喚起も記載されているようなので「宣伝だからダメ」と言うことは無いと思います。

このPDFによると1位はFirefox 1.0.7だそうです。Firefoxは1.0系はメンテナンスされてませんよね。Google AnalyticsのログによればこのブログにFirefoxでアクセスしているユーザのうち約13%は修正済みの脆弱性があるFirefoxでアクセスしていると思われます。賛否両論あるようですが自分が使っているソフトウェアがメンテナンスされているか知っておく事は重要だと思います。多くのユーザは自分が使っているソフトウェアがメンテナンスされているものなのか、されていないものなのか気していないです。時にはこういった注意喚起も必要と思いますが、これらを目にするのは普通のユーザではなくコンピュータを生業とする人達がほとんどでしょうね…

アンチウィルスソフトは普通に使われるようになりましたが、インストールされているがメンテナンスされている物か、脆弱性を含まないかチェックするソフトウェアがあると非常に便利だと思います。アンチウィルスソフトのメーカにがんばってもらって追加機能として付けてほしいですね。ウィルスのシグニチャ更新に比べればかなり簡単(?)にデータベースの維持はできそうに思えます。

とろろで、このホワイトペーパーにMS製品が無いのは選択基準のせいらしいですが、IEが載っていないのは危険なことは周知の事実だからとか?IEが危険と書いても話題にならないからとか?(実際「IEが危険です」と書いても話題にならないでしょうね)しかし、ユーザ数なども含めて選択するなら最も危険なアプリはダントツでIEだと思います。

セキュリティ対策は全体的な整合性が重要ですから、バージョンが古くて危険なソフトウェアなってしまっているソフトがインストールされている場合に警告するアプリは必要ですね。何故今までメジャーになるような製品が無かったのでしょうね?

ところで自分で「よくあるバージョンが古くて危険ソフトウェアのトップ5リスト」を作るならこんな感じでしょうね。

– Webブラウザ
– Webブラウザのプラグイン(Flash、音声、映像再生のプラグイン)
– インスタントメッセンジャー(Skypeもこれに含む)
– メールクライアント
– PDFリーダ(Acrobat Readerだけでなく、Linux等で利用されているフリーPDFリーダにも脆弱性がある)

なんだかここに取り上げているホワイトペーパーと同じようなリストになりますね。

爆発ノート

既に色々なところで紹介されているようですが、本当すごいですね、この爆発の仕方は。PCのリコール情報にも注意が必要ですね。

ところで燃料電池は可燃性の燃料を使いますがやはり爆発の危険性があるのでしょうかね?

また別の文字エンコーディング問題

HTTPヘッダでASCIIを文字エンコーディングに設定していてもISO-8859として解釈してしまうブラウザ(Firefox、Operaなど)とASCIIとして解釈するブラウザ(IE)とが在るためIPSなどのフィルタをすり抜けられるかも知れない、という話。珍しくIEの方が標準に厳格(?)に対処しています。

リンク先のページをIE 6で表示すると7bit ACSIIでは無視されるべき8ビット目が無視され読める文字列が表示されますが、Firefox 1.5では8ビット目を無視せずISO-8859として解釈してしまい文字化けしているように表示されます。IEの動作の方が仕様的には正しいように思えますが、Firefox、Operaの動作の方が安全ですね。

どちらかと言うとWeb開発者が注意すべき問題ではなく、JavaScriptの脆弱性を利用した攻撃などエンドユーザ側で問題になる可能性がある問題です。しかし、<, >等がどうなるのかは書いてないですね。IE6ではHTMLの特殊文字も普通に8ビット目を無視して処理するのかな?文字エンコーディングの取り扱いが関連ではいろいろありすぎで本当に困ります…

このブログには書いていませんがBOM(バイトオーダーマーク)でフィルタをすり抜けられる問題もありました。文字エンコーディング関連の問題はまだ出尽くしたとは思えないのでこれからも色々出てくるのでしょうね。

プログラム等、内部の文字エンコーディングは決めておくべき

あるMLでプログラム内部の文字エンコーディングは決めない事にしている、と言う意見を目にしました。プログラムを利用するシステムにより複数の文字エンコーディングがあるのでプログラム内部の文字エンコーディングを指定しない方が便利であることが理由だそうです。このような方針でも安全なプログラムは書けますが、セキュリティ上お勧めできない設計方針と思います。

2000年2月に公開されたCERTのXSS脆弱性問題の中でダイナミックページの文字エンコーディングは必ず指定する、と言う対策が書かれていますが、これと同様の理由でセキュリティ上の問題になってしまう場合があります。XSS問題としては文字エンコーディングを指定しない場合、ブラウザが文字エンコーディングを自動的に検出して表示する事になります。ブラウザが文字エンコーディングを自動検出すると、検出した文字エンコーディングによってはXSSが可能になる場合があります。

確か、昨年くらいに「文字化けしたページの文字エンコーディングを変えるとXSSが可能になる」と言うことでページの文字エンコーディングを変えると意図しないJavaScriptが実行される危険性が指摘されていました。こちらは文字エンコーディングの自動認識ではなく、ユーザが明示的に文字エンコーディングを切り替える事により発生する問題ですが、文字エンコーディングの妥当性を確認していれば防げる問題の一つです。

プログラム等の文字エンコーディングを指定しない場合、複数の文字エンコーディングを含むおかしな文字列を作ってしまうリスクがかなり高くなります。おかしな文字列がプログラム内部にもありえる事を前提にコードを書くとなると、必要以上に文字エンコーディングの妥当性をチェックしないと、コードの安全性を担保できなくなります。

同様にデータベースの場合にも文字エンコーディングを指定せずに複数の文字エンコーディングを含むデータを保存している場合があります。このような運用も文字エンコーディングに関連する脆弱性を発生させやすくなる原因になります。

互換性がある文字エンコーディングでも表現できる文字が異なるので困る場合があります。例えば、UTF-8とUTF-16ではUTF-8で表現できる文字はUTF-16よりかなり多いです。(注:実際にはUTF-16でも確か200万ほどのコードポイントを表現できるので、現状で困ることはほとんどないです。実際にはSJISを使っていて困る、などの場合が多いと思います。)

セキュリティ的にはシステム内部で利用する文字エンコーディングを指定しない場合と指定する場合を比べると、文字エンコーディングが指定されている方がはるかにコードが分かりやすく安全性も高くなると思います。プログラム等、内部の文字エンコーディングは指定できるシステムの場合、必ず文字エンコーディングは決定しておくべきと考えています。システムによっては内部で使用する文字エンコーディングは決め打ちでUnicodeを採用しています。

PHPはプログラム内部の文字エンコーディングを指定できます。デフォルトはISO-8859-1になっていてHTTP入力、スクリプトの文字エンコーディングを内部エンコーディングに自動的に変換する場合に利用されます。PHP6に備える意味からもUTF-8を内部エンコーディングに設定するのが良いかと思います。

French Microsoft Web site hacked

The attackers were likely able to penetrate the server running the Web site due to faulty configuration, Microsoft said in a statement Monday.

設定ミスだそうです。いわゆるページの改ざんだったようです。

http://experts.microsoft.fr/default.aspx

http://www.zone-h.org/index2.php?option=com_mirrorwrp&Itemid=44&id=4181592

の様な画面に改ざんされていたそうです。
トップページを改ざんされていたのですね。これは痛い…

Excel 0 Day攻撃のFAQ

メモ。Excel 0 Day攻撃のFAQ。

6/14にポストされ、6/16にマイクロソフトも脆弱性を確認とあります。XP上のExcel 2003/2002では確認されているそうです。Excel 2000は幾つかのベンダが影響あり、としているそうです。

最近MS Officeアプリの0 Dayが流行っているので注意が必要と思います。次はOOoとか?

PHPのバージョン統計 – 半数はPHP4.3ユーザ

PHP 4.4.2が増えてきているようですが、半数近くが4.3ユーザだそうです。
PHP 5系は低空飛行の状態のようです。

http://www.nexen.net/images/stories/phpversion/200605/evolution.milieu.en.png

アップグレードがいかに難しいかを表している数値だと思います…
セキュリティホールもあるのでスクリプトで対策するなど必要な処置やセキュリティ上の評価が行われているか心配になります…