SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

プログラミング未経験から始めるPHP入門

セキュリティ対策をしてみよう!
プログラミング未経験から始めるPHP入門~応用編(5)

第12回 クロスサイトスクリプティングとSQLインジェクション


ダウンロード サンプルソース (4.2 KB)

SQLインジェクション

 クロスサイトスクリプティングと同じく、入力フォームにSQL文を記述することで攻撃される場合があります。

 例えば、現在作成しているECサイトでは、ログイン時に以下のSQL文を実行しています。

SELECT * FROM m_customers WHERE customer_code = '入力されたID' AND pass = '入力されたパスワード';

 ログインを行うためのテキストボックスに、悪意のあるユーザーが次のように入力したと想像してみてください。

 ID:空白

 パスワード:';DELETE FROM m_customers;

 この場合、以下のように2つのSQLが実行されることになります。

SELECT * FROM m_customers WHERE customer_code = '' AND pass = '';DELETE FROM m_customers;

 1つ目のSELECT文は特に意味がありませんが、2つ目のDELETE文が問題です。このDELETE文が実行されると、m_customersテーブルの全レコードが削除されてしまいます。mysql_query命令では複数のSQL文の実行が不可能なため削除はされませんが、使用する命令文やデータベース環境によってはそのような攻撃も可能です。

 この問題は、テキストボックスに入力された'(シングルクオート)や;(セミコロン)などのSQLとして意味を持つ文字がそのままSQLの一部として解釈・実行されてしまうことで発生します。このような攻撃を「SQLインジェクション」と言います。本来は、外部からの入力文字によってSQLの構文に影響が出てはなりません。

SQLインジェクションへの対策

 SQLインジェクションへの基本的な対策として、「プリペアードステートメント」を用いてSQLを実行する方法があります。プリペアードステートメントとはデータベースが提供するSQLの実行方法の1つで、予め実行するSQLのテンプレートを作成するようなものです。例えば以下のようにSQL文を記述します。

$sql = "SELECT * FROM m_customers ";
$sql.= "WHERE customer_code = ? ";
$sql.= "AND pass = ? ";

 上記のように、実行するSQLをあらかじめテンプレートとして記述しておき、実際に入力フォームなどで利用する際には、次のように記述します。

$stmt =  $mdb2->prepare( $sql );
$stmt->execute();

 見覚えがありませんか? 実は、前回作成した、MDB2を用いたサンプルで既にプリペアードステートメントを使用しています。

 この?(クエスチョンマーク)の部分は「プレースホルダ」と呼ばれ、PHPでいう変数の役割を果たします。プリペアードステートメントは、このプレースホルダの部分に具体的な値(上記の例ではIDとパスワードの文字列)が設定されていない段階でSQLの構文を解析し、その後でプレースホルダに具体的な値を設定します。

IDが「oie」、パスワードが「codezine」の場合のプリペアードステートメントの動作イメージ。構文全体を解析した後で?マークの部分を具体的な文字列に差し替える
IDが「oie」、パスワードが「codezine」の場合のプリペアードステートメントの動作イメージ。構文全体を解析した後で?マークの部分を具体的な文字列に差し替える

 従って、悪意のあるユーザーがIDやパスワード欄に'(シングルクオート)などの記号を入力しても、SQLの構文が既に解析された後ですから、構文に対して影響が及ぶことはありません。


 また、このプリペアードステートメントは、繰り返し実行するSQLを高速に実行するための仕組みでもあります。具体的な使用方法などの詳細は、参考サイトをご覧ください。

 これまではSQLを実行するための最も単純な命令であるmysql_queryを使用してきましたが、今後はこの連載でも、上記のようにプリペアードステートメントを用いて記述していきます。

参考サイト

まとめ

 今回は、セキュリティの重要性を知ってもらい、セキュリティに対しての意識を持ってもらうために、これまで作成したプログラムに基本的なセキュリティ対策を行いました。しかし、これだけではまだまだ不十分で、実際にWebアプリケーションを外部に公開する際には、必要な対策は他にもあります。参考資料などをもとに良く調べ、必ず対策が十分かチェックしてから公開するようにしましょう。

今回のまとめ
  • 入力フォームにHTMLやJavaScript等を直接書き込む事で、ブラウザに期待しない動作をさせる攻撃手法を「クロスサイトスクリプティング(XSS)」と呼ぶ。
  • クロスサイトスクリプティング対策のうちの一つに、変数値を画面に出力する際に、htmlspecialchars命令を用いる方法がある。
  • 入力フォームにSQLの構文を直接書き込む事で、開発者が期待しないデータベース操作を行わせる攻撃手法を「SQLインジェクション」と呼ぶ。
  • SQLインジェクション対策のうちの一つに、プリペアードステートメントを用いる方法がある。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
プログラミング未経験から始めるPHP入門連載記事一覧

もっと読む

この記事の著者

大家 正登(オオイエ マサト)

デジタルハリウッド『PHP 講座』講師。学生時代、スペイン語を専攻していたものの何故かプログラム言語に心が傾き、近所のフリープログラマーに弟子入り修行。その後中堅 SIer に 3 年間所属し、現在はフリーエンジニア。仕事の傍らジャズを演奏し、コントラバス 2 台と同居中。(ITエンジニア・大家正登のWeb...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4347 2009/10/08 15:28

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー