• BPnet
  • ビジネス
  • IT
  • テクノロジー
  • 医療
  • 建設・不動産
  • TRENDY
  • WOMAN
  • ショッピング
  • 転職
  • ナショジオ
  • 日経電子版
  • PR

  • PR

  • PR

  • PR

  • PR

SQLインジェクションを根絶!セキュア開発の極意

第8回■主要言語の文字エンコーディングの対応状況を押さえる

文字コードに関する注意点(4)

2009/03/09 日経コミュニケーション

 文字コードの問題に正しく対応する前提として,アプリケーションが稼働する基盤ソフトウエアがマルチバイト文字列処理に対応している必要がある。特に問題となるのが,言語処理系とデータベース管理システム(DBMS)である。利用者の使い方が正しくない場合も,ぜい弱性が混入することがある。このため,今回は主要言語とデータベース(MySQLとMS SQL Server)のマルチバイト文字対応状況について説明する。

文字列の処理単位は文字単位かバイト単位か

 Webアプリケーション開発で人気のあるスクリプト言語の多くは,かつては文字列をバイト単位で扱っているものが多かった。以下のPerlスクリプトは“漢字”という文字列の長さを表示するものだが,ソースの文字エンコーディングによって結果が変わる。具体的には,Shift_JISやEUC-JPの場合は4,UTF-8の場合は6と表示される。原因は,このスクリプトが文字列の内部表現上のバイト数を表示してしまうためである。

[画像のクリックで拡大表示]

 開発者にとって,これでは不便である。スクリプト言語は簡便にアプリケーションを開発できることが魅力なので,日本語も文字単位に扱いたい。このため各スクリプト言語は,文字列処理のマルチバイト対応により,日本語なども文字単位に扱えるようになりつつある。先の例を「文字単位」に扱うようするには,以下のように「use utf8;」という1行を追加して,ソースをUTF-8で保存する。

[画像のクリックで拡大表示]

 このスクリプトを実行すると,今度は2と表示される。use utf8;宣言した場合,Perlは文字単位の文字列処理を行っていることがわかる。次にPerlを含む主要なWebアプリケーション開発ツールの対応状況を説明しよう。

◆PHP
 現行バージョンのPHP5.2.9は,言語処理系本体ではマルチバイト文字に対応しておらず,マルチバイト文字列処理はmbstring拡張モジュールが実行する。言語処理系本体が日本語対応していないため,PHPソースコードをShift_JISで記述すると5C問題が発生する。例えば以下のようなコードはコンパイル・エラーになる。

[画像のクリックで拡大表示]

 5C問題のメカニズムを説明しよう。「"表"」の文字コードは図1のようになる。「表」のShift_JISとしてのコードは「0x95 0x5C」だが,PHPではこの2バイトが独立した2文字であると解釈する。

図1●「"表"」の文字コード
図1●「"表"」の文字コード

 0x5C(バックスラッシュ)はPHPの文字列リテラル中では特別な意味があり,後続する「"」と結びついて,リテラル中の「"」自体を示すものと解釈される。このため,文字列リテラルを終端するダブルクオートが「バックスラッシュに食われ」,リテラルが閉じられていない状態となり,PHPの文法エラーになる。

 このPHPの5C問題への対策としては以下の二つの方法がある。

  • PHPをソースからコンパイルし直し,その際に--enable-zend-multibyteオプションを指定する
  • PHPソースを記述する際の文字エンコーディングとしてShift_JISを避け,EUC-JPかUTF-8を使用する

 正当なアプローチとしては「--enable-zend-multibyte」オプションを付けてPHP自体をコンパイルし直すべきだが,このオプションは実績としてはあまり広く使われていないようだ。それよりは,対症療法的ではあるが,後者のShift_JISを避ける方法が広く使われている。

 現状のPHPの文字列は単なるバイト列として実装されており,文字単位の処理ではない。一方,次のメジャーバージョンであるPHP6は,内部文字エンコーディングがUTF-16になると発表されている。近い将来のPHP6対応に備えて,今後PHPで開発するアプリケーションについてはUnicodeを使うことをお勧めする。入力,出力,ソースコードの記述に使用する文字エンコーディングをUTF-8とすればよい。

 また,PHP本体がマルチバイト文字列に対応していないことから,利用予定の拡張モジュールについてもマルチバイト文字列対応していることを個別に確認する必要がある。第7回で例に挙げたmysql_escape_string関数が,まさにそれだ。mysql_escape_string関数はマルチバイト文字列に対応していないため,mysql_real_escape_string関数を使用するべきである。

ここから先はITpro会員(無料)の登録が必要です。

  • 1
  • 2
  • 3

あなたにお薦め

連載新着

連載目次を見る

今のおすすめ記事

  • 【記者の眼】

    戸籍のマイナンバー対応を阻む2つの壁

     住民票と並んで個人にとってなじみの深い公的書類に戸籍がある。その戸籍をマイナンバーに対応させるための法制化の取り組みが本格化した。住民票や課税証明書と同様に、マイナンバーに基づく情報連携によって行政機関への戸籍謄抄本の提出を不要にして、国民の利便性向上と行政事務の効率化につなげるのが狙いだ。

ITpro SPECIALPR

What’s New!

経営

アプリケーション/DB/ミドルウエア

クラウド

運用管理

設計/開発

サーバー/ストレージ

クライアント/OA機器

ネットワーク/通信サービス

セキュリティ

もっと見る