PHP 5.4でのAccessorとPHP 5.5以降で検討されているAccessor
12月 16th, 2011二回目のPHP 5.4 Advent Calender用のエントリです。
今回はPHP 5.4より後のPHP(5.5かな?)で利用可能になると思われるAccessorの仕様について紹介します。まずはAccessorのおさらいから。
PROVE for PHP Version 1.1.0
12月 13th, 2011リンク: http://www.provephp.com/ja/
PROVE for PHP Version 1.1.0を公開しました。特に重要な変更はログデータ構造の変更と各種オーバーライド機能の調整です。
今までext3/ext4ファイルシステムの場合、ディスク容量を使い切る前にパフォーマンスが低下してしまい大きなデータを保存できませんでした。データ構造を見直す事により大きなデータでも安定して動作するようになっています。
PostgreSQL 9.0から使える識別子とリテラルのエスケープ
12月 11th, 2011PostgreSQL Advent Calender用のエントリです。
エスケープ処理が必要なのにエスケープ用のAPIが無い状態は良くありません。エスケープしないために動かないのはまだ良い方です。エスケープが必要なのにエ スケープをしなくても動いてしまい、セキュリティ上の問題となる場合もあります。全てのアプリケーション・ライブラリはエスケープが必要なデータに対するAPIを持っておくべき です。今回はPostgreSQL 9.0から追加されたエスケープ関数を紹介します。
PostgreSQL使い始めて最初の頃に気づくのはuserなどの予約語がフィールド名に使えない事かも知れません。例えば、
yohgaki@[local] test=# CREATE TABLE user (name text);
ERROR: syntax error at or near "user"
行 1: CREATE TABLE user (name text);
と失敗してしまいます。これはuserがPostgreSQLの予約語であるためSQL文の識別子として使用できないからです。MS Accessからデータベースに入った方には識別子に日本語を使う場合も多いので、PostgreSQLでは日本語のテーブル名やフィールド名はそのままでは使えない事に気が付いた方も多いのではないでしょうか?
第一回 岡山PHP勉強会のスライド
12月 8th, 2011昨日は第一回の岡山PHP勉強会お疲れ様でした。参加枠を何度か拡大しても60名の満席でした。初回ということでプログラマ目線からのセキュリティ対策の基本を解説させていただきました。セキュリティってわかりづらい、何をすれば良いのかわからない、という声はよく耳にします。短い時間でしたが考え方の基本は概ね説明できたと思います。
重要なことは口頭で説明したので資料だけみてもよくわからないとは思いますが、勉強会の資料を公開します。なにかございましたらツイッターなどで問い合わせて下さい。ツイッターには岡山PHP勉強会のハッシュタグ (#okaphp) を付けると他の方にも分かりやすいと思います。
次回の岡山PHP勉強会は2月だそうです。
追記:Integrityの訳はネットを検索してきた訳語の「統合性」を使っていましたが、違和感があったので調べてみました。JISでは「完全性」と訳されているので正しい用語に修正しておきました。
PHPのセッションアダプション脆弱性克服への道のり
12月 5th, 2011PHP Advent Calender用のエントリです。
PHPのセッション管理は非常に簡単です。セッションをsession_start()で開始して$_SESSION配列を使うだけです。便利で簡単なセッションモジュールですがセッションアダプションに脆弱であるため、一般に言われてる「ログインする時にはsession_regenerate_id()を呼ぶ」コーディングではセッションアダプションに脆弱になってしまいます。
まずは危険性と対策を紹介します。
PHP 5.4から配列定義は超簡単に、そして落とし穴も
12月 2nd, 2011リンク: http://www.php.net/manual/en/language.types.array.php
PHP 5.4 Advent Calender 2011用のエントリです。(まだ空きがあるので是非どうぞ)
このエントリを書いているのは11/23です。初めの方から重いネタだと後の方が苦労する(?)ので軽い話です。
現時点ではPHP Manualの配列のページには記載されていませんが、配列の定義が簡略化されます。まず現状の配列の定義方法は
<?php
$a = array('foo'=>123, 'bar'=>456, 789);
var_dump($a);
こんな感じですね。これを実行すると
$ ../php-src-5.4/php arr.php
array(3) {
["foo"]=>
int(123)
["bar"]=>
int(456)
[0]=>
int(789)
}
このような出力になります。array()と定義するのは面倒だ、との声は昔からあったのですが遂に[]で配列が定義できるようになりました。つまりこう書けるようになります。
gihyo.jp セキュリティ対策が確実に実施されない2つの理由
11月 29th, 2011gihyo.jpで新しい記事が公開されました。
なぜ簡単な対策で防げる脆弱性でもセキュリティ対策が確実に実施されないのか?それには理由があります。
その理由とはこの2つではないでしょうか。
- セキュリティ対策とコーディングのベストプラクティスは相反することを理解していない
- セキュリティ対策の基本中の基本を理解していない
続きは
http://gihyo.jp/dev/serial/01/php-security/0044
でご覧ください。
こちらはその記事のはてなブックマークです。
http://b.hatena.ne.jp/entry/gihyo.jp/dev/serial/01/php-security/0044
コメント一つ一つにコメントを付けるつもりはありませんが、モノリシックなコードと処理が重複しているかいないかは関係ありません。またセキュリティ対策が重複していないと「多重のセキュリティ」を実装している事になりません。
バリデーションが仕様の話、という意味は理解できません。出力時のバリデーションは出力結果を利用するシステムが誤作動しないようにするためのセキュリティ対策です。出力はバリデーションするしか方法がない場合が多くあります。出力先は多岐にわたり、エスケープ関数もヘルパー関数も何もない、というケースはよくあります。
「多重のセキュリティ」とは同じチェックやセキュリティ対策をするということではありません。もちろん同じチェック・対策をしても構わないのですが、一般に異なるレイヤーや場所でセキュリティ対策を繰り返し行う事を「多重のセキュリティ」対策と言います。”重複”と記載したので分かりづらかったのかも知れないですね。
入力時のバリデーションコードと出力時のバリデーションコードは同じコードが使える場合もありますが別のコードを使うべきです。別のコードを使わないと「フェイルセーフ対策」の意味もなくなります。
システム構築にアーキテクチャとよいコーディングスタンダードが必要なのと同じで、セキュリティにもアーキテクチャとコーディングスタンダードが必要です。入力、ロジック、出力を別のシステムとして考えるのはアーキテクチャの話と言えると思います。入力を切り分けるのは比較的簡単ですが、出力は簡単ではありません。文字列を加工し一部がエスケープ処理済みだったり、ヘルパーを使って処理したり、別の関連システムとのやり取りがあったり、と一度にまとめて処理する事が難しい場合が多いです。フレームワークの制約があったりして、フレームワークのベストプラクティスに従うと出力する部分を切り出す事が不可能な場合もあります。このよう場合はコーディングの話と言えると思います。
よく知らないのに、というのも面白いコメントですね。Railsの基本仕様とそれに影響を受けたフレームワークの話をしています。誤読ですね。文章は一旦書くとひとり歩きする物ですからある程度は仕方ないのでしょう。仕事柄、Railsは最新版ではなくよく使われているバージョンを使っているのですが、3.2とかではバリデーションのアーキテクチャが改善されているでしょうか?またそのうち確認することにします。
入力のバリデーションと出力のエスケープが重複したセキュリティ対策であっても「多重のセキュリティ」として両方実施する、が理解できていないのは「多重のセキュリティ」を理解していないのでしょう。「PHPになぜ」という部分は「Webアプリになぜ」とタイトルを変えた方が良いのかも知れません。開発者に基本的なコンセプトや現状の理解が足りてないから脆弱なアーキテクチャの理解ができなかったり、プリペアードクエリがセキュリティ対策として不完全な対策であるという簡単な事も理解できないのだと思います。
RailsをDisっているからコミュニティは反応した方が、というコメントもありましたが逆にRailsを使い込んでる人なら同じ意見だと思います。プログラムなので、もちろん入力のチェックを最初に行う事は可能ですが、フレームワークが提供していた基本機能はデータベース保存前のバリデーションです。この仕様に困ったなあ、と思った事がある人こそ本当にRailsを使っていた人なのではないかな?
ところで、たしかプリペアードクエリが万能かのように説いていたIPAのセキュリティ対策の文書でも、最新版のSQLインジェクション対策では「エスケープ」を最初に解説しています。何が正しいのか、考え方の基本として正しいものはどう反論しても正しいので無駄な努力はやめた方が良いと思います。
この文書ではまずリテラルのエスケープ方法から解説し、3.3のまとめの図では正しく、エスケープで組み立てるしか無い場合はそちらを優先し、次にプログラムクエリが使える環境ではプリペアードクエリなどを使うような図になっています。RailsでもPHPのフレームワークでも同じですがquoteメソッドを使う場合、実際にはエスケープしています。エスケープを正しく理解していないとこれらの実装が正しいのかプログラマが判断できないので適切な解説だと思います。残念なのはPostgreSQLのエスケープ手法が解説されていない点です。今のPostgreSQLはSQL標準に則り、'(シングルクオート)は'(シングルクオート)でエスケープします。libpqにはリテラルを正しくかつ完全に処理できるようエスケープするPQescapeLiteralが追加されています。(PHPではpg_escape_literalとして利用できるようになります) これでエスケープすると E'文字列' という形でエスケープを行い、SQL標準のエスケープである事が明示されます。おかしな使い方でSJISテキストを使っても誤作動することが無いようになっています。APIをサポートするプラットフォームがまだ少ないからこれは仕方がない部分でしょう。あって当然だった識別子のエスケープも解説されていないのは残念ですね。一般論として識別子のエスケープについては解説があった方がよいでしょう。プリペアードクエリを使っていてもエスケープが必要なケースです。紹介しないと完全な解説にはなりません。
同じ事はサニタイズに対する批判でも起きています。入力サニタイズがセキュリティ対策の切り札のように言われていた頃、私はホワイトリスト方式に入力のバリデーションこそが正しいセキュリティ対策で、ブラックリスト方式のサニタイズは不完全で誤った対策である、と言っていました。いろいろ反論もありましたが現在では「入力はバリデーションすべき」に反論する人はほぼ居ません。出力対策はエスケープが基本である、という持論に反対された方も多いですね。しかし、出力対策はエスケープが基本であるとすることに反論するようでは、分かってない人と思われるようになる日も遠くはないでしょう。
しかし、ネガティブなコメントには具体的な誤りの指摘や反論が皆無ですね。はてブの文化なのでしょうか?はてなのサービスは悪いものではないように思いますが、今ひとつメジャー感が出てこないのはこういう部分に原因があるのかも知れないですね。
PHP5.3.9RC2とPHP5.4.0RC2リリース
11月 24th, 2011PHP 5.3.9RC2とPHP5.4.0RC2がリリースされました。
ところで、公式WikiのリリーススケジュールによるとPHP 5.3.9のEOLはPHP 5.4.0のリリース後半年後に予定されています。
https://wiki.php.net/rfc/releaseprocess
1年後にはセキュリティパッチの提供も停止の予定です。私は期間が短すぎると思いますが、、、 皆さん、マイグレーションの準備をしましょう。
セッションのクッキーを設定する場合のベストプラクティス
11月 24th, 2011HTTPセッションは通常クッキーを利用して行います。クッキーを利用したセッションの場合、お薦めする設定は以下の通りです。
- ドメイン名は指定しない
- パスはルート(/)を指定する
- セッション管理用のクッキーはセッションクッキー(有効期間0)にする
- httponly属性を付ける
- 可能な場合は必ずsecure属性をつける
- 複数アプリケーションを利用する場合はsession.nameまたはsession_name()でセッションクッキー名で指定する (アプリケーションの固有名デフォルトで設定し、設定項目として変更できるようにする)


