========================= Webセキュリティ基礎知識 ========================= | PHPやJavaScriptでウェブサービスを作成するときに、セキュリティに関する知識がないと脆弱なウェブサービスを作りがちです。 | Webセキュリティに関する知識を身につけて、脆弱性対策を行いましょう。 | | また、脆弱性の対策以前に、プログラムをしっかりと書くようにしましょう。 | バグを極力減らすことや、バリデーションをしっかりと行うことがセキュリティの観点からしても最も大切なことです。 クロスサイトスクリプティング攻撃 ======================================= | クロスサイトスクリプティング攻撃は、HTMLフォームに悪意のあるJavaScriptを挿入することにより成立します。 | JavaScriptを利用して複数のサイトを横断させるなどすることで攻撃が成立します。 .. code-block:: html
名前を入力してください
| このようなフォームからPOSTされた値を .. code-block:: php | PHPで受け取り出力するプログラムがあった。 | 通常であれば、名前のフォームに「山田」などの文字列が入力されるはずなので | PHPでの出力結果は「山田さん」のようになるはずです。 | ところが、名前フォームに .. code-block:: none | などと入力すると、PHPでの出力結果が .. code-block:: html さん | となってしまい、JavaScriptが動作してしまいます。 | このJavaScriptに悪質なコードが含まれていた場合、サイトの利用者が被害にあう可能性があります。 | また、他の脆弱性の踏み台にされることもしばしばあります。 対策 -------------------------- PHP標準関数であるhtmlspecialcharsを使うことで、HTMLとして解釈される文字列をエスケープすることができます。 .. code-block:: php 上記の出力結果は .. code-block:: none <script>alert('XSS成功');</script>さん | このようになります。 クロスサイトリクエストフォージェリ攻撃 ======================================== | クロスサイトリクエストフォージェリは、別のサイトに用意した罠のリンクを踏ませることで | ユーザーが意図しないインターネットショッピングサイトでの購入や、 | 掲示板に意図しない発言が自分のPCから書き込まれたりする攻撃です。 .. code-block:: html
(上記ソースコードはWikipediaより引用) | 上記のようなページをユーザーが閲覧した瞬間にhttp://example.com/bbs/register.cgiに文章が送信されてしまいます。 対策 ----------------- .. code-block:: html
このように隠しフォームで、毎回変わる暗号(ワンタイムトークン)を保持し、セッションにも同一の暗号を保存しておくことで、 双方が一致しているかを確認することで対策することができます。 暗号は予測不能な文字列とし、隠しフォームに予め入力する値はハッシュ値などにしておくとよいでしょう。 セッションハイジャック攻撃 =================================== | セッションハイジャックはログイン済の状態を悪意ある人が乗っ取る攻撃です。 | ログイン済みの第3者のセッションIDを盗み出すことで、乗っ取る方法の他に | こちらが指定したセッションIDを使ってログインさせることで、乗っ取る「セッション固定攻撃」というものもあります。 | URLから流出 ----------------------------------- | PHPでは、Cookieが利用できない場合、URLでセッション管理をする設定があります。 | php.iniで利用するか設定することができます。 | 利用すると、URLの末尾にセッションIDが表示されます。 | | この時、サイト内からリンクをたどって他のサイトに移動すると | リファラからセッションIDが流出することがあります。 .. note:: リファラはどこから来たかを知るために使います。主にアクセス解析や広告などに役立ちます。直前に見ていたURLが含まれます。 | URLでのセッション管理は脆弱なので使わないようにしましょう。 XSSによる流出 ---------------------------------- | セッションをCookieで管理している場合、 | Cookieの中にセッションIDが保存されています。 | | CookieにはJavaScriptからもアクセス可能なため | XSSの脆弱性がある場合、悪意ある人にCookie内のセッションIDが盗まれる場合があります。 | .. code-block:: javascript console.log(document.cookie); | 対策としてはXSSと同様になります。 セッション固定攻撃による流出 ----------------------------------- | ログイン前からセッションIDが割り当てられ、ログイン後も同じセッションIDが使われるサイトの場合 | セッションIDを外から指定されて、固定されてしまうという脆弱性があります。 | | 例: .. code-block:: none test.php?PHPSESSID=aaaaaaaaaaaaaaa | のようにしてアクセスするとセッションIDが「aaaaaaaaaaaaaaa」になります。 | ログイン後も同じセッションIDが割り当てられる仕様の場合、 | セッションID「aaaaaaaaaaaaaaa」を使えばセッションハイジャックすることができます。 | | 悪意ある人が上記のようなURLを利用させることで、特定のセッションIDでログインさせることで | 乗っ取ることが可能になります。 セッションハイジャックを見破るには ------------------------------------------ | 通常の使用ではブラウザの言語やユーザーエージェントが途中で変わることはありません。 | このような情報が途中で変わった場合、再度パスワードを入力させるなどするとよいでしょう。 SQLインジェクション攻撃 ==================================== | SQLインジェクションは、プログラムの設計者が意図しないSQL文を攻撃者が挿入することで、データベース内のデータを改竄したり盗み出したりする手法です。 | .. code-block:: php query("SELECT * FROM user WHERE id = '". $_POST['user'] . "' AND pass = '". $_POST['pass'] . "'"); もし、$_POST['pass'] に 「' OR 1 = 1」を入れた場合、実行されるSQL文は .. code-block:: mysql SELECT * FROM user WHERE id = '' AND pass = '' OR 1 = 1 | となり、全てのユーザーのデータを取得することができてしまいます。 | | この例以外にもセミコロンで区切ることで別のSQL文を連結させて挿入してしまうことも考えられます。 対策 ------------------------ | PDOのプリペアドステートメントを使用することで、防ぐことができます。 | 詳細はPDOの項目を参照してください。 .. toctree:: :maxdepth: 1 14_pdo