CakePHPでのセキュリティ対策メモ

百式さんのブログIDEA*IDEAの記事「CakePHPのAuthComponentではまったところ」から、以前に小生が「人力検索はてな」でした質問にリンクされた記念(同じ問題に直面したようで嬉しい)として、CakePHPのセキュリティ対策について途中までまとめて放置していたメモをアップします。

---
CakePHPで開発した「30日ブログ」は、不特定多数が利用するウェブアプリケーションであるためセキュリティ対策にはかなり気を使いました(一応ウェブディレクターの端くれとしてもこの辺は慎重に)。
そしてウェブアプリケーションの一般的な脆弱性については、CakePHPがある程度まで自動的に処理してくれます(フレームワークの素晴らしいメリット)。
そこでCakePHPと代表的な脆弱性3つについてまとめました。

●SQLインジェクション
・概要:ユーザーが任意のSQLを実行できデータベースが不正操作される。価格.comが昔くらった。
・PHPの対策:入力値をエスケープする。DBごとに関数が異なるので使い分ける〔mysql_real_escape_string(),pg_escape_string()〕。
・CakePHPの対策findreadなどの組込関数は自動処理されるので対策不要。ただし自分でSQLを組み立てて実行している場合はセオリー通りの対策が必要。

●クロスサイト・スクリプティング(XSS)
・概要:ユーザー入力がそのままHTMLに表示され任意のコードが実行される。はまちさんの得意技。
・PHPの対策:HTML出力時にサニタイジングする〔htmlspecialchars($str,ENT_QUOTES)〕。
・CakePHPの対策viewでサニタイジングする。省略記法h()。echoも含めてe(h($value))で覚えよう。

●クロスサイト・リクエスト・フォージェリ(CSRF)
・概要:管理者権限をもつユーザーにURLをクリックさせて不正な操作を強いる。相手は死ぬ。
・PHPの対策:ワンタイムチケットを発行する。
・CakePHPの対策:・・・
今回CakePHPで開発していてMVCモデルを採用するCakePHPはCSRFの脆弱性が生じやすいのではと思いました(素人の感想です)。
MVCモデルではhttp://example.co.jp/モデル/コントローラ/パラメータとなりますが、プログラムの作り方によってはhttp://example.co.jp/user/delete/1というURLをクリックすることでuser_id=1が削除されてしまいます。
そこで「ログインしたユーザーしか自分のIDは削除できないことにすれば」という処理を加えても、ログインしたユーザーが<a href=http://example.co.jp/user/delete/1>エロ動画</a>なんでリンクを思い余ってクリックしたら、ログイン状態が継続している場合は同様に実行されてしまうのです。

CakePHPでの対策方法を調べると色々あるのですが、急に敷居が上がってしまい、また同一ページ内に複数のフォームがあった場合にSecurityコンポーネントがうまく動きませんでした。
"クロスサイトリクエストフォージェリ対策" フォーラム - CakePHP Users in Japan
(小生は無理やりな対策を施しましたが現在のバージョンでは正式な対応方法があるのでしょうか?)
CakePHPだからCSRFが危険と言うわけではないですが、参考書通りに作成すると危ないなーと感じた次第です。
---
フレームワークのメリットはアプリケーションの機能に集中して開発ができるところだと考えています。
CakePHPもセキュリティ面をカバーしてくれるので安心して開発ができました。
セキュリティの専門家に怒られそうですが・・・。
[

CakePHPでのセキュリティ対策メモ

| 「CakePHPでのセキュリティ対策メモ」のはてなブックマークはてなブックマーク - CakePHPでのセキュリティ対策メモ | IT・Web関連 Web制作, 30日ブログ, PHP | comments (0) | trackbacks (0) | 人気blogRanking ]

CakePHP(MySQL)でちょっと変わった検索条件。

久しぶりのCakePHPネタです。30日ブログに機能を追加しました。
http://30daysblog.com/
30日ブログ


数ヶ月ぶりにソースコードを覗けば、もはや自分で書いたものとは思えない世界が広がっていました。
それでも既存コードをコピペしてイジリながらで、思っていたより簡単に機能追加。
フレームワークでMVCが分離されていることで、後から見返してもわかりやすく、機能の追加がしやすいということを実感しました。

●ランダム表示
DBに登録されている「テーマ」をトップページにランダム表示(3件)するようにしました。
$home_theme = $this->Theme->find('all', array(
'limit'=>3,
'order'=>'rand()',
));

'order'=>'rand()'はCakePHPではなくMySQLの実装("order by rand()")です。
ランダムな数値を出して、それをidの検索条件にして・・・など考えていましたが簡単でした。

●カンマ区切りフィールドの検索
DBに登録されている「テーマ」をカテゴリー別に表示するページを追加しました。
http://30daysblog.com/themes/cateview/1
cateviewという、何ともダサいネーミングのアクションです。

各「テーマ」レコードは「カテゴリー」フィールド(category_id)を持っているのですが、テーマが複数カテゴリーに属するように"1,3,5"のようにCSVでcategory_idを保持しています。
本来DB設計としてはやってはいけないことなんだと思いますが、諸々の面倒を考えこのような形をとっています。

このCSVの中から特定のcategory_idを取得する方法についてWhereのLIKE検索を考えました。
SELECT * FROM db WHERE category_id LIKE '%$param%'
しかしこれでは、$paramが"1"の場合、"1"以外に"11"や"10"などにもマッチしてしまいます。
まさに同じような課題を人力検索はてなで見つけました。
MySQLでデータの保存方法について質問です。 1つのフィールド内に「1,2,3」と言うようにカンマ区切りのデータを保存する箇所があります。通常、この部分は正規化して別テー.. - 人力検索はてな

なるほど正規表現を使うのかー。
以下CakePHPでの実装。
function cateview($param = null) {
$data = $this->Theme->find('all', array(
'conditions' => array('Theme.category_id REGEXP' => "^$param$|^$param,|,$param$|,$param,"),
));
$this->set("data", $data);
}


CakePHPではfindを使えば柔軟にSQL文を作成できます。
以下、自分でコピペする際の雛型。
$data = $this->Model->find('all', array(
'conditions' => array("Model.id" => $param,"Model.hoge <>" => ""),//条件式。","でand。比較演算子の位置に注意。
'fields' => array('id', 'title'),//取得するフィールド。未指定は全件。
'recursive' => 0,//アソシエーションの取得数
'order' => 'Model.created desc',//取得順序
'limit' => 100,//取得件数
));


DB設計をいじらない表面上の処理であれば色々と簡単に実装できそうです。
[

CakePHP(MySQL)でちょっと変わった検索条件。

| 「CakePHP(MySQL)でちょっと変わった検索条件。」のはてなブックマークはてなブックマーク - CakePHP(MySQL)でちょっと変わった検索条件。 | IT・Web関連 30日ブログ, PHP | comments (2) | trackbacks (0) | 人気blogRanking ]

CakePHPで更新pingを送信(PEARのXML/RPC)+RSS配信

先日公開しました「30日ブログ」
引き続き機能の追加などを行っており、今回は日記作成時に「更新ping」を送信させるようにしました。
「更新ping」とは検索エンジンなどに対する更新通知であり、更新ping送信するとクローラーが巡回してくるので早めに検索エンジンなどに反映されるようになります。

●更新ping送信の実装


ググって以下の二つを参考にしました。
PHPでBlog更新ping (XML-RPC)を送信する|PHPプログラムメモ|プログラムメモ
PHPでPingを送信すべし:High5.log〜Webとか〜

どちらもPHPの場合ですがcontrollerにほぼ丸々コピペでいけます。
ただCakePHPでPEARライブラリを使う方法がいまいちわからず。
調べると色んな手法があるようですが、小生の場合は下記のようにしました。

1.PEARのRPC.phpを以下に保存
/app/vendors/pear/xml/RPC.php

2.更新pingを送信するfunctionの冒頭に以下の1行を追加。
App::import('Vendor', 'XML_RPC', array('file'=>'pear'.DS.'xml'.DS.'RPC.php'));

PEARライブラリも簡単に使えるとなると拡張性も十分だ。
日記の入力にwiki記法を使えるようにもしました。
CakePHPのヘルパーからPEAR::Text_Wikiを使ってお手軽変換 - 「最果て」の支部

以上で日記作成時に更新pingが送信されている・・・はずです。
#本当にクローラがやってきてるのか動作確認がいまいち。
#successの反応が返ってきてるので、たぶん大丈夫なんだろうけど。

●RSS配信


更新pingを送信すると、クローラはそのサイトのRSSをチェックする場合があるようです。
そこでRSS配信も実装。これはCakePHP1.2単体で実現できます。
参考サイトはこちら。
CakePHP1.2でRSSフィードを使う | エムティシステム

あれ?エラーになる。
どうやらレイアウトファイルが無かったようです。
/cake/libs/view/template/layouts/rss/default.ctp
  ↓
/app/view/layouts/rss/normal.ctp


さらにdebugレベルを0にします。
Configure::write('debug', 0);
CakePHP Note:RSSヘルパー

あれ?それでもダメだ。
試行錯誤の上、normal.ctpの下記をコメントアウトしたら動いた。何で?
//echo $rss->header();

最後にブラウザやクローラにRSSの在り処を知らせるためのリンク、RSS auto-discoveryをviewに仕込みます。
複数の RSS を RSS auto-discovery で提供するには
<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="xxxx.rss" />
これでRSS配信をブラウザでも確認することができました。

思ってたよりも簡単に二つの機能を実装できて、あらためてフレームワークの威力に驚いています。
[

CakePHPで更新pingを送信(PEARのXML/RPC)+RSS配信

| 「CakePHPで更新pingを送信(PEARのXML/RPC)+RSS配信」のはてなブックマークはてなブックマーク - CakePHPで更新pingを送信(PEARのXML/RPC)+RSS配信 | 30日ブログ Web制作, PHP | comments (0) | trackbacks (0) | 人気blogRanking ]

CakePHPをさくらのレンタルサーバで公開した。

先日公開しました30日ブログは、さくらインターネットのレンタルサーバで運用しています。
レンタルサーバは「さくらのレンタルサーバ」|さくらインターネット

このブログ自体がさくらレンタルサーバなので請求を1本にまとめたいという、それだけが理由だったのですが、思いのほかCakePHPの導入が簡単に済みました。
以下、作業内容をまとめます。
続きを読む>>
[

CakePHPをさくらのレンタルサーバで公開した。

| 「CakePHPをさくらのレンタルサーバで公開した。」のはてなブックマークはてなブックマーク - CakePHPをさくらのレンタルサーバで公開した。 | IT・Web関連 30日ブログ, PHP | comments (0) | trackbacks (0) | 人気blogRanking ]

「30日ブログ」開発の経緯・企画趣旨など

昨日に公開しました30日ブログについて、開発の経緯、企画趣旨などを簡単にまとめたいと思います。

・自分のウェブサービスを公開したい
小生は非IT企業で、ウェブディレクションのような感じと思われることを仕事にしています。
毎日ウェブに触れる中で、自分の企画、アイデアを思い通りに具現化したいという思いが膨らみます。
↓読んで刺激を受ける記事。
田口元の「ひとりで作るネットサービス」探訪 - ITmedia Biz.ID

・でも続かない
仕事柄プログラミングの基礎知識が必要だとPHPの講習会に参加したのが2006年9月8日。なんと2年前。
講習会終了後はPHPがどんなものか概観を把握できましたが、その次につながらず。
やっぱり継続するものがないとダメだ。

・時間の経過
そして忙しさ(と人生のイベント)で時間が1年経過して2007年12月。
百式さんの主催する忘年会議に参加します。
「忘年会議2007」に行ってきました。
この後の懇親会にも参加したのですが、周りのすげーギークっぷりに恐縮。
自分もウェブサービスを公開させるぞという気持ちを新たにします。

・そしてCakePHP
その固い決心から早くも半年が経過w ダメダメだw
2008年5月からCakePHPの勉強を始めます。
初心者がCakePHPの勉強を始めるよ。
CakePHPは百式さんのブログで存在を知っていました。
CakePHP修行! アーカイブ | IDEA*IDEA
またこの頃に関わっていた仕事の案件で開発会社がCakePHPを使うとのことで、いまが契機だと着手します。

・アイデアを思いつく
そしてこの頃に読んだブログ。
勉強が苦手な人向けの「遅延評価勉強法」 : ロケスタ社長日記
まずは課題、目標を立て、それを解決しながら勉強を進める。
忙しい社会人にとってはこのような「パラシュート勉強法」が向いているようだ。
そしてけんすうさんは実際に100日プログラミングという企画を完遂していました。
その終了後の反省の中に「100日というのは妥当なのか?30日とかのほうがいいかな?」とのコメントがありました。

それなら30日に限った課題を立てられるサービスがあると面白いんじゃないかな?
小生が開発するウェブサービスのテーマが決まりました(インスパイヤされました)。

・そして半年
最初の1ヶ月はわけもわからず参考書をなぞるだけ。
そりゃPHPもよく知らないのに、さらにフレームワークを学ぶなんて・・・。
途中で1ヶ月放置したりしながら何とか土日休日をつぶして開発を続け、
初心者がCakePHPをはじめる件
ようやくアイデアを形として陽のあたる場所に出すことができました。

ウェブサービスを公開したことで一つの満足感を感じてしまいますが、自身でもこのサービスを使い新しい課題を立て、今後ともサービスの継続、改善に努めたいと思います。

・今後実装したいこと
・複数人でテーマを共有(みんながんばれ)
・複数の目標を立てる(いろいろやろうぜ)
・30日を超える目標を設定(いのちをだいじに)

公開に至るまでのCakePHPの技術的な諸々については、また後日に。
とりあえずsakuraサーバでの公開はとっても楽でした。
[

「30日ブログ」開発の経緯・企画趣旨など

| 「「30日ブログ」開発の経緯・企画趣旨など」のはてなブックマークはてなブックマーク - 「30日ブログ」開発の経緯・企画趣旨など | 30日ブログ IT・Web関連 | comments (2) | trackbacks (0) | 人気blogRanking ]

ウェブサービス「30日ブログ」を公開しました。

念願だったウェブサービスの公開にこぎつけました。
30日ブログ(30daysBlog.com)
30日のテーマを決めてブログを書こうというサービスです。
まだ仮公開で調整しながらの運用ですが、良かったらご利用ください。

30日ブログ(30daysBlog.com)
30daysblog.png


裏テーマとしては自己管理ができない自分に必要だったので。
日々の記録をつけながら、色々な目的・目標を達成していきたいと思っています。

それにしても、ウェブに関わる仕事をしてるとはいえ、エンジニアでもない小生がここまでの機能を実装したサービスを開発できるとは思わなかった。
フレームワーク「CakePHP」の威力は絶大です。

参考
初心者がCakephpをやる件(これまでの経緯)
[

ウェブサービス「30日ブログ」を公開しました。

| 「ウェブサービス「30日ブログ」を公開しました。 」のはてなブックマークはてなブックマーク - ウェブサービス「30日ブログ」を公開しました。 | 30日ブログ IT・Web関連, Web制作, PHP | comments (0) | trackbacks (0) | 人気blogRanking ]
人気記事(はてなブックマーク)
▼すべて表示
generated by レビュー・ポスター
1/1
30日ブログ