予告:4/30にZendFramework 1.8がリリースされました。次回はZendFramework 1.8の新機能の紹介とZendFramework 1.8を使って,ゲストブックアプリを作り直します。
機能的な問題以外ににも,前回作った簡単なゲストブックを使ってみるといろいろな問題があることが分かります。
- 日本語が使えない
- エスケープのセキュリティ対策が十分でない
- ZendFrameworkらしくないViewでのエスケープ
しかし,簡単なゲストブックアプリケーションを“普通”に作る場合とZendFrameworkを使って作る場合の違いを比べると,アプリケーションの作り方の違いがよく分かったと思います。
ZendFrameworkを使ったほうが,手順が多くて面倒に感じたかも知れません。しかし,それはアプリケーションが単純すぎてフレームワークのメリットを感じられなかっただけです。アプリケーションの規模が大きくなり,複雑になるとフレームワークのメリットが感じられるようになります。
データベースの設定修正
まずはデータベースの設定を修正します。データベースには2つの問題があります。
- 文字エンコーディング
- ユーザアカウント
文字エンコーディングの問題
どんなアプリケーションでも利用する文字エンコーディングを正しく取り扱わないと,セキュリティ上の問題となります。特にWebアプリケーションでは文字エンコーディングを利用し,SQLインジェクションやJavaScriptインジェクションなどを行うさまざまな攻撃方法が知られています。
今回はPostgreSQLをデータベースサーバとして利用しています。PostgreSQLはMySQLやMS SQL Server,Orableなどと同様に,文字エンコーディングを指定できるようになっています。
PostgreSQLサーバのインストールや設定によっては,デフォルトの文字エンコーディングがUTF-8になっていない場合があります。
デフォルト文字エンコーディングがUTF-8の場合
[framework@localhost www]$ psql -U postgres -l
List of databases
Name | Owner | Encoding
-----------+---------------+----------
guestbook | postgres | UTF8
mediawiki | mediawikiuser | UTF8
postgres | postgres | UTF8
template0 | postgres | UTF8
template1 | postgres | UTF8
(5 rows)
デフォルト文字エンコーディングがSQL_ASCIIの場合
[yohgaki@dev $ psql -U postgres -l
Password for user postgres:
List of databases
Name | Owner | Encoding
-----------+---------------+-----------
guestbook | postgres | SQL_ASCII
mediawiki | mediawikiuser | SQL_ASCII
postgres | postgres | SQL_ASCII
template0 | postgres | SQL_ASCII
template1 | postgres | SQL_ASCII
(5 rows)
PostgreSQLのSQL_ASCIIエンコーディングは,バイナリエンコーディングと呼んでもよいエンコーディングです。文字エンコーディングが正しいかのチェックは行われません。どのような文字エンコーディングであっても保存できますが,不正な文字エンコーディングの文字列はセキュリティ上の問題となる場合があります。このため,特別な理由が無い限りSQL_ASCIIは使用してはならない文字エンコーディングです。これは,PostgreSQL以外のデータベースサーバを利用している場合でも同じです(※1)。
もし,利用されているデータベースの文字エンコーディングがUTF8以外の場合,データベースを再作成する必要があります。
- ※1
PostgreSQLのデフォルト文字エンコーディング(templateデータベースの文字エンコーディング)はinitdbコマンドでデータベースを初期化する際に決まります。「initdb -E utf8」と,ほかのコマンド同様,-Eオプションで文字エンコーディングを指定できます。
ユーザアカウントの問題
データベースユーザが特権ユーザである「postgres」アカウントを利用しています。特権ユーザを通常のデータベースアクセスに利用することは好ましくありません。一般ユーザを作ってアクセスすべきです。特権ユーザを利用している場合,アクセス制限が機能しません。使用中のデータベース以外のデータベースでも簡単に破壊できてしまいます。
通常,アプリケーションごとに別のユーザを作成すべきです。
データベースの問題を修正
PostgreSQLの場合,文字エンコーディングを変更するにはデータベースを再作成する必要があります。データを保存したい場合,データベースのバックアップを取得する必要があります。PostgreSQLの場合は,pg_dumpコマンドを使用してバックアップを取得できます。今回はサンプル用のデータベースなので単にデータベースを削除します。
データベースの削除
$ dropdb guestbook
ゲストブックデータベースにアクセスする新しいデータベースユーザを作ります。
$ /opt/PostgreSQL/8.3/bin/createuser -U postgres -W zfguestbook Shall the new role be a superuser? (y/n) n Shall the new role be allowed to create databases? (y/n) n Shall the new role be allowed to create more new roles? (y/n) n Password:zfguestbook(※実際には表示されません)
通常ユーザ,データベース作成権限なし,データベースロール(ユーザ)作成権限なしで作成します。通常,ユーザ名と同じパスワードは使用すべきではありませんが,便宜上ユーザ名と同じパスワードを設定しました。
文字エンコーディングとオーナー名を指定してデータベースを作成
$ createdb -U postgres -O zfguestbook -E utf8 guestbook
作成したデータベースを確認
[yohgaki@dev PHP-ZendFramework]$ psql -l -U postgres
Password for user postgres:
List of databases
Name | Owner | Encoding
-----------+---------------+-----------
guestbook | zfguestbook | UTF8
mediawiki | mediawikiuser | SQL_ASCII
postgres | postgres | SQL_ASCII
template0 | postgres | SQL_ASCII
template1 | postgres | SQL_ASCII
(5 rows)
psqlコマンドでデータベースを一覧すると新しいオーナーとエンコーディングでデータベースが作成されていることが確認できます。
テーブルの作成
$ psql -U zfguestbook -f /www/guestbook/guestbook.sql guestbook
作成したテーブルの確認
$ psql -U zfguestbook guestbook
Password for user zfguestbook:
Welcome to psql 8.3.5, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
guestbook=> \d
List of relations
Schema | Name | Type | Owner
--------+------------------+----------+-------------
public | guestbook | table | zfguestbook
public | guestbook_id_seq | sequence | zfguestbook
(2 rows)

