自社の周年サイトの立ち上げでAWSを使用したメモ。


4ヵ月ぶりのブログ更新です。ここ1~2ヵ月は、仕事で複数ウェブサイトの案件が詰まっており、体調を崩して風邪を3週間ほどこじらせています。久しぶりに扁桃腺スパークもしました。

そのうちの1つの案件として自社の周年サイトの立ち上げを行いました。
身バレしてしまいますが下記サイトとなります。
法研 創立70周年特設サイト

私自身がウェブディレクターのような立ち位置なので実際のデザインやコーディングは他社さんに発注しています。
ただ、サーバ環境については後学のためにAWS(Amazon Web Services)で構築しました。
アマゾン ウェブ サービス(AWS) - クラウドコンピューティングサービス

実際のお客様案件ではサーバ運用は専門会社さんに委託するわけですが、自分自身で使っていないとサービス内容や感覚がわからないので自社サイトで試験運用してみた次第です。
以下、その時のメモとなります。
続きを読む

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(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で更新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をさくらのレンタルサーバで公開した。

先日公開しました30日ブログは、さくらインターネットのレンタルサーバで運用しています。
レンタルサーバは「さくらのレンタルサーバ」|さくらインターネット
このブログ自体がさくらレンタルサーバなので請求を1本にまとめたいという、それだけが理由だったのですが、思いのほかCakePHPの導入が簡単に済みました。
以下、作業内容をまとめます。

続きを読む

  • 他のブログ

    育児で買ったモノたち
  • Twitter

  • 最近の投稿

  • 最近のコメント

  • はてなブックマーク

  • RSS購読

    RSS Feed RSS - 投稿

  • カテゴリー

  • 月別

  • カレンダー

    2017年6月
    « 5月    
     1234
    567891011
    12131415161718
    19202122232425
    2627282930  
  • プロフィール


    健康・医療系の出版社でウェブに関わる営業企画と浅い技術。Webディレクター?
  • キーワード検索