Webアプリケーションのセキュリティ基礎
■第2話:インジェクション攻撃とその対策
(最終更新日:2023.10.09)

(絵が小さい場合はスマホを横に)
「不正な命令から守る」
前回はセキュリティ全般について概要を説明した。
今回は、中でもインジェクション攻撃に絞って説明を行う。
インジェクション攻撃は、日本でも世界でも毎年上位に挙がるサイバー攻撃の一つである。
幾つか種類があり、それぞれ対策があるので、今回は具体的にどうすべきかを説明する。
1.サーバーサイドへのインジェクション攻撃
Webアプリケーションにおいて、作成するプログラムはクライアントサイド(フロントエンド)とサーバーサイド(バックエンド)がある。
今回は、サーバーサイド側のインジェクション攻撃について説明する。
サーバーサイドは、ユーザー情報等を含む機密情報を含んだデータベースを管理している。
他にもサーバーの挙動を制御する重要な命令が数多くある。
サイバー攻撃から、これらを守ることは安全なWebアプリケーションを構築する上で必要不可欠である。
インジェクション攻撃は、攻撃者が悪意のあるデータをアプリケーションへ「注入」し、それを介してシステムを不正に操作する一連の攻撃手法を指す。
この攻撃の成果として、先ほど挙げたデータへの不正アクセスやシステムの制御を行うことを目的とする。
2.SQLインジェクション
SQLインジェクションは、ウェブアプリケーションの入力フィールドにSQLのコードを挿入することで、データベースを不正に操作する攻撃手法である。
例として、ログインフォームを考える。ユーザー名とパスワードの組み合わせを確認するSQL文が不適切に構築されていると、
攻撃者は特定のSQL文を入力することで認証を回避したり、データベースの内容を盗み出すことができる。
下記の最初のSQL文はユーザー認証を行うためのSQL文である。
ユーザー名とパスワードを入力させて、合っている場合にその人に適した情報にアクセスできるようになる。
しかしながら、2つ目のように、ユーザー入力の一つ目(username) の部分に「' OR '1' = '1' --」と入力すると、
正しいユーザー名とパスワードを入れずしてSELECT文が成立し、認証が通るようになる。
SQLインジェクション攻撃の例
このような不正な入力から守るには、例えばPHPの場合は以下のようなプレースホルダを用いて記述する。 ユーザーからの値を直接SQL文に入れずに、エスケープした文字を入力するようにする(3、4つ目の命令、bindParamでエスケープした文字を注入)。 エスケープされる文字はシングルクォート (')、ダブルクォート (")、バックスラッシュ (\)、NULLバイト (\0)、改行 (\n)、キャリッジリターン (\r)、タブ (\t)などであり、 先ほど行ったような命令は成立しない。これにより、SQLインジェクション攻撃を防ぐことができる。
プレースホルダによる安全なSQLの実行
3.OSコマンドインジェクション
OSコマンドインジェクションは、不適切に処理された入力を通じて、攻撃者がOSのコマンドを実行する攻撃手法だ。 この攻撃を防ぐには、外部コマンドを直接呼び出さない設計や、入力値の厳格な検証が必要である。 攻撃の例としては、以下のようなPHPコードとアクセス例が考えられる。 ファイル名を指定してデータを表示する命令だが、表示にサーバー側のcatコマンドを使用している。 file名部分に「secret.txt;rm -rf」と入力されると、secret.txtをcatコマンドで実行した後に、「rm -rf」されファイルを全て消されてしまう。
OSコマンドインジェクションの例
このような攻撃を防ぐためには、外部コマンドを実行する際にユーザー入力を直接使わないことが重要である。 また、どうしても必要な場合には適切にエスケープや検証を行う必要がある。 さらに、セキュアなAPIや関数を使用して、外部コマンドの実行を避ける方法もある。 基本的な対策としては、外部コマンドを使う部分にユーザー入力を関連させないと覚えておこう。
4.コードインジェクション
コードインジェクションは、攻撃者がアプリケーション内でコードを実行する攻撃手法である。 これは、動的にコードを評価する関数(例:eval())の誤用に起因することが多い。 これらの関数の使用は避けるか、非常に慎重に行う必要があります。 攻撃の例としては、以下の通りである。ユーザーの入力に基づいて実行できるeval関数が使われており、 そこに悪意のあるコード(echo file_get_contents('/etc/passwd'))をFormなどで入力されると、 この場合はパスワードを盗みとられてしまう。
コードインジェクションの例
OSコマンドインジェクションと同様、サーバーサイドの命令は、クライアント(ユーザー)に行わせないというのが基本的な防御方法だろう。
5.まとめ
今回、SQLインジェクション、OSコマンドインジェクション、コードインジェクションにおいて具体的なコードを交えて、
攻撃例とその対策方法を紹介した。実際にWebアプリケーションを開発したことがあれば、
なぜ必要か、このような対策が有効かという部分は理解できたと思う。
コンテンツの有用性は、安全にWebサイトを使えることが前提となっている。
この辺りの防御を自動的に行ってくれるWebフレームワーク(Rails、Laravel、Djangoなど)の機能に頼りきることなく、自分でも対策できるよう、正しい知識を身に着けよう。
▼参考図書、サイト
安全なウェブサイトの作り方
情報処理推進機構