CakePHP1.2.8以前、1.3.5以前に重大なセキュリティホールが見つかりました。
ただちにコアを最新版にアップデートすることをお勧めします。
参考: CakePHPのSecurityComponentに深刻なセキュリティホールが見つかりました - Shin x blog
2011/12/30
CakePHP 1.3.14と2.0.5のリリース(訳)
訳
CakePHPコアチームはCakePHP2.0.5*1と1.3.14*2を素早くリリースできたことを誇りに思います。
2.0.4から合計で、90以上のコミットがあり、40以上の問題が解決されました。変更の完全なリストは変更ログページ*3で見ることができますが、以下に2.0.5で成された変更の簡単なまとめを挙げます:
- Cacheにおける返り値が正しく直されました。ドキュメントにあるように、falseが常に失敗を指し示します。
- foreignKeyのないhasOneアソシエーションによる連鎖削除(cascading deletes)が正しく動作するようになりました。
- SQLiteのために、キャッシュファイルのファイル名に「"」*4を含まないようになりました。
- テーマのアセットファイルのファイル名が空白文字を含む場合でも、ディスパッチャーを通して正しく配信されるようになりました。
- ViewTaskで二重に複数形化(pluralization)されることを修正しました。
- Cacheヘルパーはcallbacksオプションを使用しているときの多くの問題が修正されました
- TextHelper::excerpt()がドキュメント通りに動作するようになりました。
- $tablePrefixを使うモデルが遅延読み込みされた時、正しく動作するようになりました。
- namedパラメータとクエリパラメータについてのルーティング問題が解決されました。
- Shell::$pluginが追加され、より正しいヘルプと使用方法ドキュメントが生成できるようになりました。
- CakeEmailが同一のメールでインラインと通常の組み合わせの添付ファイルを正しく扱えるようになりました。またインライン添付ファイルも動作するようになりました。
1.3ブランチでは、1.3.13から35以上のコミットがあり、25以上の問題が解決されました。変更の完全なリストは変更ログページ*5で見ることができますが、以下に1.3で成された変更の簡単なまとめを挙げます:
- 画像のフォーム送信ボタンでアセットのタイムスタンプ付けがされるようになりました。
- Postgresのリテラル値を含むvirtualFieldsが正しく動作するようになりました。
- ユーザ定義のヘッダはEmailComponent::reset()でリセットされるようになりました
- CookieComponentで2.0.xアプリケーションで生成されたクッキーを読めるようになりました。
- PHP5.4との互換性が改善されました。
- アセットの相対プロトコルURLが正しく動作するようになりました。
- TextHelper::excerpt()がドキュメント通りに動作するようになりました。
私たちは素晴らしいリリースになるように、2.1ブランチとそのシェイプアップに熱心に仕事をしてきました。
2.1は2.0の完全な後方互換性を持ち、多くの有用な機能を追加しました。
2.1で何が予定されいて、何が完了したかのリストは、ロードマップ*6と、進行中の2.1の移行ガイド*7を見てください。
素晴らしいCakePHPのコミュニティに、目覚ましい活躍全てに、今一度の感謝を述べます。
あなたの貢献と愛がなければ、CakePHPはなかったことでしょう。
後書き
Bakeryのリリース記事の訳です。
http://bakery.cakephp.org/articles/markstory/2011/12/29/cakephp_1_3_14_and_2_0_5_released
2.1ブランチでの活発な動向にも目が離せなくなってきました。
前リリースが緊急リリースだったこともあり、長い期間と多めの変更になっていますが、軽微なものが多いのですぐにバージョンアップして良いことでしょう。
それでは皆様、良いお年を:D
*1:http://github.com/cakephp/cakephp/zipball/2.0.5
*2:http://github.com/cakephp/cakephp/zipball/1.3.14
*3:http://cakephp.org/changelogs/2.0.5
*5:http://cakephp.org/changelogs/1.3.14
*6:http://cakephp.lighthouseapp.com/projects/42648/development-roadmap
*7:https://github.com/cakephp/docs/blob/2.1/en/appendices/2-1-migration-guide.rst
2011/09/30
Mediaプラグインをアップロード処理の基本から学ぶ(2) - 制限, 検証
検証環境
PHPのアップロード処理
PHPのアップロードサポートでは、基本的にアップロードされたファイルの以下の情報が$_FILES*1に連想配列として入ります。*2
- name - アップロード元のファイル名
- type - MIMEタイプ
- size - ファイル容量(バイト)
- tmp_name - 一時ファイルとして保存されたアップロードファイルのパス
- error - アップロードに成功したか(エラー内容)
これらを元に、ファイルの検証・移動を行います。
1. name - アップロード元のファイル名
送信元から送られてくるファイル名が入りますが、これはあまり信用してはいけません。
悪意のあるファイル名の送信により、プログラム上で対策を行わないと上位ディレクトリのファイルにアクセスされる危険性もあります。
また、ファイル名がマルチバイトである場合、ファイルシステムによってはアクセスが不可能であるかまたは困難となる可能性があります。
これを回避するために、Transferビヘイビアのtransfer()メソッドを、モデルが同名のメソッドを実装することによりオーバーライドする必要があります。
具体的な実装に関しては、docs/TUTORIAL at from davidpersson/media - GitHubを参考にしてください。
2. type - MIMEタイプ
MIMEタイプが入りますが、マニュアルにもある通り、送信側から送られてきたヘッダーの内容がそのまま入るので、これは信用できません。
Mediaプラグインは、上述のmmライブラリを使ってMIMEタイプを自動解析します。
MIMEタイプの解析の方法は様々ありますが、例えばFileInfoなどを使って解析することができます。
これはmmのMime_Typeの設定で変更することができます。
また、解析済のMIMEタイプを用いて、checkMimeType*3バリデーションが使用できます。
3. size - ファイル容量(バイト)
ファイルのバイト数が入ります。
PHPの設定によりファイルサイズも制御できますが、アップロードされるファイルの種類によってファイル容量を抑制する場合は、アプリケーション側で処理をする必要が出てきます。
これをMediaプラグインはcheckSizeバリデーションで行います。
4. tmp_name - 一時ファイルとして保存されたアップロードファイルのパス
アップロードされたファイルは、一時的なファイルとしてファイルシステムに保存されます。(/tmpや、C:\TEMPなど)
これをPHPアプリケーションが取り扱えるディレクトリにコピー、または移動する*4ことによって、アプリケーションがはじめてそれを単純なファイル
として操作することが可能になります。
なお、移動先はMediaプラグイン設定のtransferになります。(後の記事で説明)
5. error - アップロードに成功したか(エラー内容)
PHPのエラー定数を用いて判別しますが、要は
などの場合分けです。
アップロードされていない、もしくは正しくアップロードが完了していない場合、Mediaプラグインはこれを無視します。
ファイルの移動
ファイルの移動を行う時に、その移動元、移動先が正しい場所であるか検証する必要があります。
ファイルの場所
もしシステムファイルにアクセスできたり、または特定のディレクトリにアップロードファイルが書き込まれることがあったら、非常に危険な事態に陥る可能性があります。
これを検証するために、MeidaプラグインのcheckLocationバリデーションが利用できます。例えば、/tmp、APP/tmp、APP/webroot/media(MEDIA定数)等を指定します。
ファイルのアクセス権限(パーミッション)
移動元のファイルは読み込み可能であり、移動先のディレクトリは書き込み可能である必要があります。
そうでない場合、アップロードが必ず失敗することは想像の範疇だと思います。
これは、MediaプラグインでcheckAccessバリデーションを使用することで検証できます。
また、移動元のファイルにもし実行可能属性が付いていたらどうでしょうか。
そうなる状況はあり得るかという疑問はありますが、実際共有サーバーなどで/tmpなどに悪意のある操作をされることは想定できます。
これを検証するために、MediaプラグインにはcheckPermissionバリデーションが用意されています。
その他の制限、検証
拡張子
拡張子そのものを制限します。これはMIMEタイプでapplication/octet-streamを許可した場合など、与えられた拡張子がアプリケーションの要件にあったものかを制限します。
これはcheckExtensionバリデーションがMediaプラグインに用意されています。
ピクセル数
総ピクセル数を制限します。
総ピクセル数が大きい物をリサイズする時に、メモリを非常に多く浪費します。
これを制限しないと、PHP、またはサーバーのメモリ限界を超えることになり、最悪ハングアップすることもあります。
また、このチェックではMediaプラグインのcheckPixelsバリデーションが利用できます。
次回予告
いかがだったでしょうか。アップロードの検証だけでも多くの面からの処理が必要になることが理解できると思います。
次回はアップロードされたファイルの変換と配置についてになります。
*1:CakePHPでは、FormHelper#file()などで出力したinput[type=file]の内容は、$_FILESからディスパッチャを通して$this->dataに格納されます。
*2:PHP: POST メソッドによるアップロード - Manual
*3:この記事で**バリデーションと表記しているものはTransferビヘイビアのものを指す
2011/09/16
Mediaプラグインをアップロード処理の基本から学ぶ(1) - 導入
検証環境
イントロダクション
Mediaプラグインとは、CakePHPのプラグインの一つです。
主にアップロードファイルを取り扱うプラグインで、CakePHPでアップロードの処理をするためのデファクトスタンダードとなっています。
このプラグインはファイルのアップロードからアップロードされたファイルの検証、DBへのメタデータの保存、変換、ダウンロード、表示、フォーム連携までを多段階に抽象化し、その恩恵として非常に柔軟な設定・拡張ができるようになっています。
バージョン
バージョンとしては、nextブランチ(1.3系、バージョン1.3.x)とmasterブランチ(1.2系、バージョン0.6.x)がありますが、nextブランチがカレントのブランチとなっており、これを使うのが推奨されています。
また、1.2系の場合は、1.3系で取り入れられた拡張方法が足りていないため、不可避の問題が生じる可能性があります。
更に、1.3系では機能が統合・削除・分割などがされているので、古い情報が役に立たない時があります。
この連載では、1.3系の解説になります。
mmライブラリ
Mediaプラグインは、バージョン1.3.0から、内部のファイル変換処理をmmライブラリ(http://github.com/davidpersson/mm)に分割しています。
このため、CakePHP以外のPHPアプリケーションでもmmライブラリを使用することによって、同機能を使用することが可能になりました。
アップロード処理の基本概念
ファイルをweb上でアップロードさせる場合、アプリケーション側では非常に多面的な処理を行います。
アップロードにかける基本的な制限
容量の制限などをPHP、httpdの設定により行います。
大容量のファイルを無制限にアップロードさせるのは、サーバー残容量に深刻なダメージを与えることがあります。
また、場合によっては違法アップロードの温床にもなりかねません。
検証
アップロードされるファイルは基本的に信用できません。
アプリケーション特有の制限、またファイルの種類による制限(画像、音声により異なるなど)をかける必要がある他、悪意のある情報(メタデータ)を取り除いてやる、または許可しない必要があります。
これを緻密にしない限り、アプリケーションの(アップロードに纏わる)品質は担保れされないことでしょう。
画像などの変換処理
サムネイルなどの画像変換を行います。
サムネイル等が必要なくても、一般的にGIFAR(変換の章で説明)などを回避するために、閲覧者に表示させるものは内部でメタ情報を削ったものを提供するため、ほぼ必須の工程となります。
ファイル情報(メタデータ)の取得
アプリケーションの要件によっては、アスペクト比、縦横の長さ、MIMEタイプなどを取得する必要がでてきます。
これらはフィールドキャッシュか、またはキャッシュ機構を用いて適切なコストに抑える必要があるでしょう。
DBへの登録
アップロードされたファイルの基本的な情報は、DBに登録するのが一般的です。
ファイルだけで管理するとなると、複雑なロジックが必要になったり、また探索のコストがスケールしなくなるなど致命的な欠陥を招きます。
ファイルアクセスへの制限
要件によっては、ファイルへの直接のアクセスを制限する必要がでてきます。
ほとんどの場合、ファイル名(URI)にランダム文字列(またはハッシュ)を割り当てることによってこれを達成できます。
権限通りのアクセス制限を施す必要がある場合は、アプリケーションを通すことによってこれを実現するべきでしょう。
次回予告
2011/07/27
CakePHP 1.3.11 と 2.0.0-beta のリリース(訳)
CakePHPコアチームはCakePHP 1.3.11 と 2.0.0-betaをこんなにも早くお見せできることを誇りに思います。1.3.11は1.3ブランチのバグ修正・メンテナンスのリリースです。2.0.0-betaはAPIの安定化の開始と、また後方互換性のない変更をこれ以上するべきでないポイントを位置づけるものですが、まだ商用システム向けということではありません。5月の下旬にCakePHP 1.3.10がリリースされてから、27以上のコミット*1と10個のチケットが解決されました。アプリケーションに影響する可能性のある変更がいくつかあります:
1.3
- Fixtureは逆順にクリア(truncated)されるようになりました。これはデータベースの制約(constraints)を伴ったアプリケーションがよりスムーズにテストを走らせることを可能にします。
- デバッグ出力からデータベースの認証情報を隠し、本番サーバーでdebug = 0とするのを忘れたユーザーを保護します。
- mod_rewriteが正しくセットアップされているかの検出のバグが修正されました。
- データソースはMysqlまたはMysqliに接続できないとき、エラーを引き起こすのではなく、falseを返すようになりました。
- 重要なCakePHPのアナウンスを表示するために、デフォルトのhome.ctpにバナーを追加しました。
2.0
2.0でコアチームは、次世代フレームワークのためのTODOリストの残り項目を実装することにおいて、大躍進を成し遂げました。私たちは新しいコミッターの大きな潮流と多くのgithubでのプルリクエストを得ることができました。コミュニティがCakePHP 2.0に興味を置いていることにワクワクしています。2.0.0-alphaから、多種多様なトピックブランチのマージを伴って、375以上のコミット*2があります。もし既にアプリケーションが2.0で動いているなら、それをアップデートする必要がある2つの大きな変更があります。最大の変更はディスパッチ(Dispatching)処理が、webrootのindex.phpファイルでCakeResponseのインスタンスを渡すことを必要とするようになるということです。また、デフォルトのルートが、アプリケーションのroutes.phpからインクルードされる必要のある専用のファイルから展開されるようになりました。このことから、app/Config/routes.phpをデフォルトで設置されているものに従って書き換えるようにしてください。このリリースの重要なポイントのクイックリストは以下の通りです:
- Microsoft SqlServer 2008 と 2011 は第一級市民となりました(訳注:手堅くサポートされたということ)。
- フォームヘルパーはモデルのメタデータを再度推測できるようになりました。コントローラが使っているモデルが何かを表すコントローラの$usesプロパティを用いて賢くヘルパーにヒントを与えることができるようになりました。これは1.3アプリケーションで$usesがパフォーマンス低下の要因になり得ると思われたことに焦点を当ててます。これはもはや2.0ではなり得ません。
- i18n展開シェルは処理にプラグインを除く、またはプラグインごとに展開することができるようになりました。
- モデルのバリデーションメッセージをi18nシェルによって自動的に展開することができるようになり、もはや1.3アプリーケーションのようにコンストラクタでメッセージを翻訳する必要がなくなりました。
- デフォルトのルートは専用のファイルに設置され、app/Config/routes.phpでインクルードされる必要があります。必ず更新してください!
- DispatcherはCakeResponseを二番目の引数で受け取るようになりました。必ずapp/webroot/index.phpファイルを更新してください!
- Model::saveAll()はリファクタリングされ、モデルがsaveMany、saveAssociated、validateMany、validateAssociatedといったメソッドをもつようになりました。
- Model::find()はリファクタリングされ、クエリー生成処理が新しいbuildQuery()メソッドでされるようになりました。
- 数多くのパフォーマンス向上。
(訳注:翻訳元で多分ここに改行が足りてない)
この時点から、CakePHPコアチームはlighthouse*3に現れるバグの修正と、gitベースでsphinxを使ってコンパイルされる新しい2.0のマニュアル*4(book)に注力します。素晴らしいドキュメントを手に入れることで私たちに手を貸そうと思っていただけるなら、どうぞ自由にレポジトリをフォークして変更のプルリクエストを送ってください。また、APIドキュメント化の向上を望んでもいますので、コードでのドキュメントブロック(doc blocks)のプルリクエストもまた非常に歓迎します!
CakeFest 2011*5が近くなったことで、開発者に早期割引価格が過ぎ去ってしまう前のチケットの購入を推奨しています。ワークショップトレーニングの証明書の授与、2トラック並行のトークセッション、多くの国際スピーカー、などなどを含んだとても多くのサプライズをこの9月のマンチェスターでお見せすることができることでしょう。まだ悩んでいるのなら、スケジュール*6を確認しておいてください!
全ての関連するコミット、チケット、ドキュメントの編集、その他フレームワークへの助力を通しての貢献に関して、多大な感謝を捧げます。あなたがいなければ、CakePHPはなかったことでしょう。
-- 訳ここまで
後書き
Bakeryのリリース記事の訳です。
http://bakery.cakephp.org/articles/lorenzo/2011/07/26/cakephp_1_3_11_and_2_0_0-beta_released
2.0のベータリリースはまだまだ先の9月ぐらいかなーと個人的に思っていましたが、もうリリースされましたね。はええ。
これは年内stableリリースも見えてきましたね。ドキドキ。
2010/07/19
CakePHP1.3.3、虹色アイス版がリリースされました(訳)
CakePHP開発チームはCakePHP 1.3.3[1]のリリースをアナウンスすることを嬉しく思います。1.3.3は1.3ブランチのメンテナンスリリースで、1.3にある機能のバグフィックスと最適化が含まれます。
先月におけるCakePHP 1.3.0のリリースから、50以上のコミットと、解決された35以上のチケットがありました。また、アプリケーションに影響することがある若干の変更があります。
- コンポーネントの beforeRender トリガはViewクラスが初期化される前に起動するように移動されました。
- FormHelper::create() は $this->domId(); を呼ぶようになりました。
- 複数回の bindModel/unbindModel 呼び出しはアソシエーションを正しくリセットするようになりました。
- TextHelper::autoLink() は、URL短縮に伴う問題を引き起こしてしまうことにより、URLにstrtolower()をしないようになりました。
全てのなされた変更を、完全な変更履歴[2]と関連したチケットをチェックして確かめてください。ドキュメント周りにおいて進行中の、コミュニティの努力に多大な感謝を捧げたいと思います。今やCookbookには19,000以上の改訂があります! また、CakeFest 2010[3]のための提案をしてくれた全ての人に、もちろん既にチケットを買った人にも、感謝をしたいと思います。もしまだチケットを手に入れていないのなら、今が今年最高のCakePHPカンファレンスに参加する絶好の機会です。7月24日までの前売り券で、早期割引のアドバンテージを得ることができます。
注意書き: このリリースの作成において虹への被害はありません。(訳注:タイトルに対してのユーモア)
リリースパッケージをダウンロードするには:[1]
変更履歴を見るには:[2]
[1] http://github.com/cakephp/cakephp/downloads
[2] http://cakephp.lighthouseapp.com/projects/42648/changelog-1-3-3
-- 訳ここまで
後書き
Bakeryのリリース記事の訳です。
http://bakery.cakephp.org/articles/view/cakephp-1-3-3-rainbow-icing-edition-released
