カテゴリー
Computer Development Security

PROVE for PHP 1.0.3を公開

私の会社で開発・販売しているPROVE for PHPを更新し、PDOオブジェクトに対応したPROVE for PHP 1.0.3の配布を開始しました。PDOオブジェクトに対応したので幅広いアプリケーションで利用できます。PROVEは非商用の個人利用の場合、無償で利用できます。問題などございましたらツイッターやメールなどでフィードバックを頂けると助かります。

http://www.provephp.com/ja/download

PROVE for PHPとはPHPの動作を詳細に記録・比較し、PHPとPHPアプリのバージョンアップが安全に行えるか簡単にチェックできるツールです。開発中のリグレッションテストツールとして利用できます。

近日中にこのブログでもいろいろな使い方を紹介したいと思っています。

追記: RHEL5系(CentOS5など)で利用できるPHP53パッケージ用RPMのダウンロードも開始しました。

カテゴリー
Computer Development Programming

PHP 5.4から利用できるtraitの利用例

PHP5.4からtraitが利用できるようになる事をご存知の方も多いと思います。

traitはコードの水平再利用を可能にする仕様拡張です。Rubyのmixinのような機能と言えば分り易いかも知れません。

誰でもtraitを利用したくなるようなコードをinternals@php.netのMLで見かけたので紹介しよう、と思って書いたのですがコピペしたコードをしっかり読んでなくておかしな所があった事を @sotarok さんに教えてもらいました。

元のコードは色々問題があるので書き直しました。こうやればアクセサーを沢山書く必要が無くなります。

カテゴリー
Computer Development

Bit module for PHP

誕生日のメッセージを送ってくださった皆様ありがとうございました!

今日は誕生日ということで多少は趣味のOSSに時間を割いてもバチは当たらないだろう、という事で簡単なPHPモジュールを書きました。PHP勉強会@東京に参加してPHPerバイナリアンの方の発表に触発された事がこのモジュールを書いた動機です。BitモジュールはバイナリアンPHPerの為のモジュールです。

https://github.com/yohgaki/bit

関数は今のところ4つだけあります。

  • string byte_get(string) – バイナリをHEX文字列に変換
  • string byte_set(string) – HEX文字列をバイナリに変換
  • string bit_get(string) – バイナリを0と1の文字列に変換
  • string bit_set(string) – 0と1の文字列をバイナリに変換

PHPではバイナリを取り扱う事が面倒だったのですがこのモジュールを使えば比較的簡単にバイナリを修正する事ができます。

初めはバイナリを配列にして返そうか、とも思ったのですが効率が悪いので単純に文字列に変換することにしました。こんな機能が欲しい!こう修正して欲しい!という方はご連絡ください。対応できるかも知れません。

ちなみに現状でもPHPスクリプトだけでバイナリを取り扱えるライブラリがあります。

http://openpear.org/package/IO_Bit

さらにZlibバイナリが扱えてしまう物まであります。

http://openpear.org/package/IO_Zlib

そしてSWFファイルを修正できてしまう物も。

http://openpear.org/package/IO_SWF

これらは@yoya さんが書かれたパッケージだそうです。凄すぎです。バイナリを操作する必要がある方はこちらも是非ご利用ください。

カテゴリー
Computer Development

RealIP Module for PHP

リバースプロキシの背後にあるPHP用に$_SERVER[‘REMOTE_ADDR’]をX-Real-IPやX-Forwarded-Forヘッダに設定されたIPアドレスに書き換えるRealIPを書きました。

https://github.com/yohgaki/realip

少しGoogleで検索しても見つからなかったので作ったのですが、既にありそうな気がします。

PHPスクリプトで書き換えても良いのですが、アプリをバージョンアップした時に忘れる可能性があります。プロキシ・Webサーバで何とかする方法もありますが、プロキシ・Webサーバの仕様に合わせた設定が必要だったり、と不便な所もありモジュールの方が便利なので書きました。同じ事をするには他の方法がありますが、必要な方はどうぞ。

多分、PHP5.2でもコンパイルできると思います。コンパイル出来なかったら教えてください。

カテゴリー
Computer Programming Secure Coding

PHPセッションアダプションをスクリプト側で修正する方法

PHPのスクリプトを使ってアダプティブなPHPセッションをアダプティブにしない方法を紹介します。

このブログで紹介していたかどうか覚えていないですが、セッションアダプション対策としてsession_regenerate_id()が導入された時に議論・紹介されているので知っている方も多いと思います。(というより、PHPerの常識ですよね?)

まずはセッションアダプションの原理と対策の復習をしておきます。

カテゴリー
Computer Development Programming

PHP 5.4の文字エンコーディング設定

PHP 5.4 RC1が公開されています。PHP 5.4のリリースが近いです。PHP 5.3の–enable-zend-multibyeの問題でバグレポートをした関係でinternals MLでメールのやり取りをして分った事とその他をまとめておきます。主にSJISを使う場合の注意点です。間違い・勘違いもあるかも知れないので気が付いたらコメントを下さい。

  • PHP 5.4はデフォルトの内部エンコーディングがISO-8859-1になる
  • SJISでコードを書く場合はzend.script_encoding=SJISを書く
  • SJISでコードを書く場合は内部エンコーディングをSJIS(mbstring.internal_encoding=SJIS)に設定する
  • SJISで出力する場合はmbstring.http_output=SJIS (output_handler=mb_output_handlerなどが必要)を設定する
  • SJISでページを書いている場合、SJISが入力になるのでmbstring.http_input=SJISを設定する
  • Zend Multibyteサポートがコンパイルオプションからランタイムオプション(zend.multibyte=On)になる
  • Zend Multibyteサポートにはmbstringが必須
  • mbstringがモジュールとしてビルドされている場合でもZend Multibyteサポートを有効にできる
  • declare(encoding=…)でスクリプト中からスクリプトのエンコーディングが指定できる

php  -c php.ini-development -d zend.multibyte=1 SJIS_script.phpとしてSJISが含まれるスクリプト(例えば、echo “表”)を実行するとSJISの文字が?に変換されてしまいます。正しく処理するには-d mbstring.internal_encoding=UTF-8などを追加し

php  -c php.ini-development -d zend.multibyte=1 -d mbstring.internal_encoding=utf-8 SJIS_script.php

などとしなければなりません。

全般的にマルチバイト文字エンコーディングのサポートが改良されていますが、以前と多少異なる部分があるので注意が必要です。

カテゴリー
Computer Development Programming

PHPのSession Adoption脆弱性

PHPのセッションモジュールはセッションアダプションに脆弱なのですが、開発者の理解が得られず何年間も放置されています。

セッションアダプション脆弱性: 未初期化のセッションIDを受け入れてセッションを確立する脆弱性。

PHPのセッションIDはデフォルトでドメイン指定無し、パスは/に設定されています。専用サイトならこれであまり困ることは無いのですが、複数のアプリケーションやユーザが利用するようなサイトでは問題になります。

例えば、Chromeはパスよりドメインが優先されるのでドメインを利用したセッションIDの固定化などが起きます。IEではドメインよりパスが優先されるのでパスを利用したセッションIDの固定化などが起きます。

session_regenerate_id()を使えばOK、と考えている人も多いようですが既に設定済みのクッキーのうちどれが優先されてしまうか?が問題であるためsession_regenerate_id()を利用してもセッションIDは変わりません。優先されないクッキーを設定しても意味がないからです。

対策としては、すべてのドメイン、パスのセッションIDと同じクッキー名のクッキーを削除(空のクッキーを設定すると削除)する事ですがあまり多くの人がやっているとは思えません。根本的な解決策は「厳格なセッション管理」を行うことです。未初期化のセッションIDは受け入れないようにすれば完璧です。

セッションIDの固定化が可能な状況では、セッションアダプションに脆弱な場合はセッションを盗まれますが、厳格なセッション管理ならセッションIDを毎回振り直そうとする事になり、セッションは盗まれません。つまり、セッションが盗まれる代わりに「ログインできない」というDoS攻撃になります。セッションを盗まれるより、DoSの方が比べる必要がないくらいマシです。「ログインできない!」というユーザが居たら「ブラウザのクッキーを削除してください」と対応すれば良いだけです。

数年前にそろそろ直したら?とsecurity@php.netにメールしたのですが、開発者の問題だと勘違いしていて修正されませんでした。今日、またphp-internal@list.php.net internals@lists.php.net に再度メールをしておきました。さて、今回はどうなることでしょう?