Hatena::ブログ(Diary)

Copy/Cut/Paste/Hatena

2010-12-02

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

13:03 |  CakePHPであることを隠蔽する (CakePHP Advent Calendar 2010 2日目)を含むブックマーク  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じゃね?」と思ってしまうのは職業病でしょうか。

このURLCakePHPの特徴かなと思います。


ただ、CakePHPには強力はルーティング機能が備わっています。(ルートの設定 :: 環境設定 :: CakePHPによる開発 :: マニュアル :: 1.3コレクション)

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さんのエントリはいつも実に裏付けされたような納得感があるものばかりでいつも勉強になります。今から楽しみですね。

cakephpercakephper 2010/12/02 13:30 Advent Calendar2日目の担当ありがとうございます!
CSSの中身にもCakeという文字がたくさん含まれています。コピーライトの文が入ってるので、隠したいならCSSは自分で0から作ったほうがいいですね。

MASA-PMASA-P 2010/12/02 16:03 data[]の件ですが、フォームの方は上記のように別の文字列にしておいて、beforeFilter(initializeのほうがいいかな?)等で$this->paramsをdataに配置し直すような方法なら、コアコードをハックしないで済むような気がします。

tfmagiciantfmagician 2010/12/02 21:39 その他によく使うので、CakePHPっぽいはPagenationのページ数ですかね。
普通に使ってしまうと、":"を含むURLになるので、そのあたりをどうやって変更してるのか知りたいです!

k1LoWk1LoW 2010/12/02 21:51 >cakephper
確かに!

>MASA-P
それも考えたのですが、確かコンポーネントの初期化のほうがbeforeFilter()より実行が早かったと認識しています。
そうすると$this->dataを前提としたコンポーネントが動かないんではないかと考え、今回は上記のような強引な手に。。。
initializeでいけますかねー。

>tfmagician
https://github.com/MASA-P/KtaiLibraryのREADMEに書いていることが正解だと思います。セパレータもroutes.phpでできるとか普通知りませんよね。
さすがCakePHP辞典の中の人。

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

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

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

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