読者です 読者をやめる 読者になる 読者になる

CakePHPであることを隠蔽する (CakePHP Advent Calendar 2010 2日目)

cakephperさんから始まったCakePHP Advent Calendar 2010。
いやあ、HtmlHelper::image()のurl属性は使っていなかったです。勉強になりました。
では、2日目の担当ということで。

CakePHPで開発されていることをアピールしたい!でも。。。

自分はCakePHPを常用していて、「開発環境のEmacsも世界で最もCakePHPに最適化されている(via cake.el)」といっても過言ではありません。
開発の効率化のための開発(陥りがちな再帰)も多くしてきて、書き捨てからプラグインまでいろいろ書いてきました。
また、もっともっと国内でCakePHP案件事例が広く公開されて欲しいと思っています。


ただ、インターネットに広く公開されるWebシステムを作成する場合、
そのWebシステムが「何で作られているか」ということが、攻撃者への攻撃の糸口として利用されてしまうということも確かです。

CakePHPであることを隠蔽してみる

というわけで、CakePHPの機能性は損なわずにできる限り「CakePHPであること」を隠蔽してみようという実験です。


CakePHPで作成されるWebシステムにはいくつか特徴があります。その特徴からCakePHPであるとわかるというわけです。
要はそれを隠していけば「PHPとは分かってもCakePHPとは分からないんじゃないか」という発想です。

デザイン

これは基本ですね。

favicon.ico

そのまんまCakePHPのアイコンです。意外に忘れがち。ちゃんと変更しましょう。

CSSのファイル名

注意。cake.generic.cssというファイル名です。CakePHPであることがバレバレです。
(※追記 id:cakephperさんより情報提供)
さらにcake.generic.cssの中にも"cake"の文字列があるのでcssの再利用は諦めるという方向で!

Cookie name

ここも意外に忘れがち。Session用のCookieの名前がそのまま"CAKEPHP"です。
app/config/core.phpを書き換えましょう。

<?php
Configure::write('Session.cookie', 'SOMEPHP');

URL

だんだん難しくなってきます。


CakePHPは「設定より規約」です。DBのテーブル名から最終的なURLまで一貫したルールがあります。
また、この規約から外れると結構面倒になるのも事実です。

URLが

http://somedomain.com/products/edit

なんかになっていると、何となく「CakePHPじゃね?」と思ってしまうのは職業病でしょうか。
このURLもCakePHPの特徴かなと思います。


ただ、CakePHPには強力はルーティング機能が備わっています。()
routes.phpでRouterクラスを使ってガシガシ変更してしまいましょう。


あと、index()、add()、edit()、delete()というデフォルトのaction名を初めから変えるというのもアリです。

inputのname属性

一番面倒な問題です。


CakePHPではコントローラやモデルで"$this->data"を多用します。
これはフォームからポストされる値に規約があるためで、これを利用して"if (empty($this->data)) {〜}"といったコードも書かれることも多いです。
これらは元をたどればFormヘルパーのメソッドが

<input name="data[Post][title]" />

という特徴的なinput要素を「出力」していて、そのフォームからPOSTされた値をCakePHPが「$this->dataに格納する」という形で実現しています。
CakePHPにとって$_POST['data']は規約として重要ということになります。


逆にこれをみれば、「ああCakePHP製だ」と分かるわけで、隠蔽するのならばなんとかしないといけません。
さらにCakePHPの機能性は損ないたくありません。


で、結局行き着いたのは「出力」する部分と「$this->dataに格納する」部分を修正するというアイデアです。
正確には「FormHelper::input()」と「app/webroot/index.php」に手をいれました。
(※なので、前提として「全てのPOSTはFormHelper::input()を利用する」が追加されています)

この修正を適用するとinput要素が

<input name="___posts[title]" />

となります。CakePHPぽくない。キモいですね。
ただ、ビューやコントローラやモデルのコードを一切書き換えることなく実現できています。

追記

コメントより

適当なページで ?url=/ を付けてトップページが出たらCakePHPの可能性大と判断できます。

例: http://bakery.cakephp.org/categories?url=/

先日 http://wp.serpere.info/archives/1883 この件で学びました。

あと test.phpcss.php にアクセスした時のエラーメッセージの形式もなんかもデフォルトでは特徴的ですね。

むー、どうしようもない。。。

まとめ

若干強引ですが、なんとか「CakePHPの機能性を損なわずにCakePHPであることをできるかぎり隠蔽する」ことはできたかなと思います。
これらはまだ実験レベルですが、今はこれをどうにかしてプラグインで解決できないものかと考えています。
あまり役にたたないかと思いますが、こういう要求もあったりするといことです。
CakePHPも大変ですね。


さて、3日目はshin1x1さんです。
id:shin1x1さんのエントリはいつも実に裏付けされたような納得感があるものばかりでいつも勉強になります。今から楽しみですね。