個人のPCを守るということではなく、Web上で注意すべきこと、特にサーバ管理者やアプリケーション開発者が忘れてはならないことを書いておく。
普通にレンタルサーバを借りていてWordpressとかを入れている程度であれば、恐らくはシステム側で対策が取られていることと思う。バージョンアップを忘れないようにすれば大きな危険は無いだろう。もちろん、決して保証するわけでは無い。
さて、この文章はボリュームが大きく挿絵も無く、読み難いかも知れないが、お付き合いいただければ幸いである。
大規模なシステムでは、サーバは3台構成を取っている。厳密にはパフォーマンスを向上させる目的でそれぞれに複数台を設置することもある、バランサ―などを追加することもあるので3層構造がベースとでも呼んだ方が正しいが、ここでは3台としておく。まずこれを確認した上で、主なリスクを攻撃の種類によって解説していきたい。
- Webサーバ:ネットに繋がっているサーバであり、クライアント(PC等のブラウザやアプリ)からのリクエストを受け取り、静的なコンテンツをWebサーバ自身から送るとともに、設定に基づいてアプリケーション(AP)サーバにリクエストを渡す。このリクエストに対する処理結果をAPサーバから受け取り、クライアントに送り返す。このWebサーバはリクエスト時の状況を確認し、アクセスを制限する等のセキュリティ機能を有するとともに、ネット側からAPサーバやDBサーバが直接アクセスされることにならないような壁の役割も果たす。
- APサーバ:Webサーバからのリクエストに対し、内部のプログラムを起動させ処理結果をWebサーバに返す。APサーバでは計算や文字列操作を行うことになるが、Wordpress等ではデータベース(DB)に接続することで様々な情報を引き出すことが主な処理となる。
- DBサーバ:APサーバからのSQL言語を用いたアクセスにより、多量のデータを格納し、これらの検索等を行う機能を有する。大規模なサービスになるほどDBの役割は重要度を増していき、どれだけ多くのデータを高速に扱えるか、検索できるか、はアプリケーションの能力と技術者のチューニングにかかっている。
WebサーバとしてはApache、APサーバとしてはPHP、DBサーバとしてはMySQLがそれぞれ個別に動くことで上記を1台で3役を担う構成を取ることもある。
では本題として、10個程度のセキュリティ攻撃について解説を行う。
XSS (Cross Site Scripting)
ターゲットとなる掲示板等に不正なHTMLやJavaスクリプトを記入し、別のユーザが閲覧した際に悪影響を与える。安全なサイトだと思ってアクセスした先に危険なコンテンツが埋め込まれていることになり被害が発生し易い。不正スクリプトの種類により様々な被害の発生が起きうる。サーバやクライアントが対策されていれば未然に防ぐことができるものであり、特にサーバ側ではサニタイズと呼ばれるスクリプトの無害化が行われる。以前から最も有名な手口であるとともに、いつになってもどこかで誰かがやらかしているものでもある。
略語としてはCSSになるはずだが、一般的にCSSはCascaded Style Sheetを意味するものであるため、敢えてXSSと略記されている。
CSRF (Cross Site Request Forgery)
不正コードを埋め込んだリンクを仕掛け、このリンクを踏んだ者がが思ってもいない結果を引き起こす。これは上記のXSSと似ており、また組み合わされて仕掛けられることも多い。XSSでは「何かをされる」ということになるが、これに対してCSRFでは「何かをさせられる」ということになる。危険性を伴うのは、サービスやサイトにログインした状態でCSRFに引っ掛かってしまうケースである。この場合、ログイン状態の権限を持ったままでコマンドや処理を実行させられることになる。サーバ側ではサニタイズとともに、呼び出し元チェックやセキュリティトークンを用いる等により、誘導されたアクセスを切り分ける必要がある。また、重要な処理を行う場合には必ず意思確認の画面を出すようにすれば、いきなり最悪の事態に陥るようなことは回避できる。この意思確認画面に相当するCSRFが仕組まれないようにすることは当然である。
このCSRFが非常に困ったものとなるのは「加害者だと思ったら被害者だった」というような事態を招くことである。あるユーザが突然不適切なことを書き込んできたとしても、それが本人の意思ではないかもしれないということなのだ。犯罪予告や脅迫メールを第三者に送信させるという事件があったが、あれはウイルスではなくCSRFによるものと推測される。
SQLインジェクション
掲示板への書き込みをデータベースで処理しているケースにおいて、不正なデータベースコマンド(SQL)を文字列に埋め込んで実行させようというものである。例えば、MySQLであれば文字列はシングルクォート「’」で区切られ、コマンド行はセミコロン「;」で区切られるため、これらの特殊な意味を持つ記号を入力することによりコマンドを実行させた攻撃が行われる。サーバ側はデータベースに送信するテキストに関するサニイタイズはもちろんのこと、そもそも数値が入るべき領域にテキストが入ったりしないような処理を組み込むことが必要となる。
OSコマンドインジェクション
一部の仕組においては、サーバのOSコマンドを利用するものがある。これに対して不正なコマンドが実行されるように仕組んだテキストを送り込むというものである。これもサニタイズが必要ということになるが、そもそも入力された情報を用いたOSコマンドを実行すること自体がこの上なく危険であり、別の方法でアプリケーションを実装すべきと言える。繰り返す、別の方法でアプリケーションを実装すべきだ。
NULLバイトアタック
これはPHP独自の仕様(バグ?)に対して行われる攻撃である。NULLバイトが文字列の終端として見なされることを悪用したインジェクションの一種となる。NULLバイトを除去するサニタイズ処理を取るか、もしくはNULLバイトが含まれているアクセスは処理を行わないようにすべきである。通常のユーザがNULLバイトを送ってくることは無いであろうから、NULLバイトの存在をチェックし、発見したらエラーにしてしまう方が良いであろう。
ディレクトリトラバーサル
アクセス時のURLに「../」等を入れ込むことにより、想定していないディレクトリのデータを開示してしまうことを狙う。例えばファイルをダウンロードするプログラムに対して、「filename=../../../../etc/passwd」のような指定をした場合、これが通ってしまうとパスワードファイルをダウンロードすることになる。指定されたファイルが想定しているディレクトリ下かどうかのチェックを行うことで回避ができる。リクエスト中にピリオド「.」やスラッシュ「/」が連続している場合は処理を止めるような工夫でも対応できる。
アップロードファイルの実行
実行形式のファイルをアップロードした後、そのファイルをURLで指定してアクセスする。単純なトロイの木馬のようなものであり、よほど迂闊ではない限りは起きにくいと考えられるが、やられた場合の被害は甚大である。起きにくいとはいえ、ファイル形式や権限設定も関係するため、それなりに対処しなければならない。アップロードされたファイルをURLで指定できない場所に置くとともに、ファイルにアクセスする際には専用のダウンロードプログラムを準備することで安全性は高くなる。アップロードファイルを画像のみに限るということも有効であろう。
スクリプトソース露呈
独自プログラムのスクリプトソース(プログラムの記述)を入手したり、パスワードを記載した設定ファイルを盗み見ることで次の攻撃に繋げる。プログラム開発を行う場合のテスト等においては注意が必要であるが該当する人は少ないだろう。なお、設定ファイルについてはアクセス権限を正しくするよう、インストール時の注意事項に従うことになる。
オープンソースであればソースは公開(オープン)されており、露呈も何もない。共同プロジェクトとして開発されてるものであれば逆に多くの技術者によるセキュリティの確認が行われていることが期待できる。
セッションハイジャック
どこかのサイトやサービスにログインした後、ログイン状態を続けている際に「セッション」という方法が用いられる。この状態を狙い、XSSやCSRFを用いてセッション情報を盗み出し、成りすましを行うことがセッションハイジャックである。セッション情報を複雑なものとする、セッション有効時間を短くする、アクセス元のIPアドレス変動をチェックする、等により対策することになる。
セキュリティホール
ブラウザのセキュリティホールが発見されたり、PHPのセキュリティホールが発見されたり、こうしたセキュリティホールに対する攻撃を行う。これらの回避はできるだけ最新のセキュリティ情報を入手し、こまめに対策を打っていくしかないのだが、日頃から疑う癖をつけておくことである程度未然に防ぐ可能性が高まる。例えば、プログラムにおいて「何もデータを代入していない変数は0が初期値」というようなことを信じないこと。例えば、アップロードされた画像ファイルに対しても一度GDやImageMagick(いずれもPHP用の画像処理ライブラリ)に読み込ませてみること。自サーバで設定したCookieであっても、違う値を使ってアクセスされるケースを想定しておくこと。
WordPressのようなアプリケーションについては、バージョン表示を消しておいた方がいいという意見がある。セキュリティ上の問題(脆弱性)が存在するバージョンだということがバレる危険性があるためだ。どのバージョンであろうと、さらにはWordpressであろうとなかろうとアタックしてくるケースもあるから、表示だけ消しても無駄という意見もある。正しくバージョンアップすることが対策であり、表示を消すことは対策ではないということには同意する。表示を消せば脆弱バージョンを検索されるリスクが減るとは思うが。
以上、文字ばっかりで解り難いが私の知っている範囲のことを私なりの理解で説明をしてきた。これから先はあなた自身の立場に応じて、自ら調べ自ら学んでいただきたい。まあ、嘘は書いていないつもりだが、こういう技術は刻々と進化していくし、この文章自体が読んだからといって具体的なことが理解できるものではないから。
最後に、まず一つ。サーバにセキュリティ問題がある場合、被害者になる可能性以上に加害者に加担する可能性が高いということを知っておいて欲しい。
そして、もう一つ。セキュリティレベルの高いプログラムを作るということであれば、サニタイズもさることながら、何をどうするプログラムかということから例外的な入力を排除するようにして欲しい。必要が無ければファイルのアップロードはさせない方が良いし、日付や数値等の入力時にはブラウザ上でのチェックを仕込みつつ例外が入力されたら不正アクセスと見なせば良い。システムの機能や操作の流れの中で必要でありかつ余分なものの無い手順を実装しつつ、悪意のあるアクセスやデータでの攻撃が必ずあるのだと考えておくことがセキュリティ確保に繋がるものだと思う。
[amazonjs asin=”4883374718″ locale=”JP” title=”PHPサイバーテロの技法―攻撃と防御の実際”]