こんにちは、佐藤です。
今回は問い合わせフォームを題材としました。
Wordpressのプラグインによるフォームの設置で対応することが多いですが
小規模サイトではスクラッチで作成することもあります。
調べていると、いくつか懸念がありました。
1、情報が分散していること
2、ソースが不明瞭であること
3、結局どうすればよいか分からないこと
セキュリティは会社の守りの部分であるため、その実装には非常に慎重になります。
上記懸念をできるだけ払拭する意味も込めて、実装の際に得た知見をまとめようと思います。
目次(想定読了時間5分)
検証環境
- PHP 7.4
- nginx + Apache2.4系
- さくらインターネットレンタルサーバー
- https://help.sakura.ad.jp/206053142
セキュリティ対策する上で参考になるサイト
IPA(独立行政法人情報処理機構セキュリティセンター)のサイト内に「安全なウェブサイトの作り方」という
PDFファイルがあります。
https://www.ipa.go.jp/security/vuln/websecurity.html
※外部サイトにリンクします
抑えるべき攻撃手法とセキュリティの対応策
クロスサイトスクリプティング
ウェブアプリケーションの中には、検索のキーワードの表示画面や個人情報登録時の確認画面、掲示板、ウェブのログ統計画面等、利用者からの入力内容や HTTP ヘッダの情報を処理し、ウェブページとして出力するものがあります。ここで、ウェブページへの出力処理に問題がある場合、そのウェブページにスクリプト等を埋め込まれてしまいます。この問題を「クロスサイト・スクリプティングの脆弱性」と呼び、この問題を悪用した攻撃手法を、「クロスサイト・スクリプティング攻撃」と呼びます。クロスサイト・スクリプティング攻撃の影響は、ウェブサイト自体に対してではなく、そのウェブサイトのページを閲覧している利用者に及びます。
引用元:IPA「安全なウェブサイトの作り方(改訂第7版)P22」
対策:
・ウェブページに出力する全ての要素に対して、エスケープ処理を施す。
・URLを出力するときは、「http://」や 「https://」で始まるURLのみを許可する。
・<script>...</script> 要素の内容を動的に生成しない。
・スタイルシートを任意のサイトから取り込めるようにしない。
・HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)の指定を行う。
・Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、TRACEメソッドを無効化する。
・クロスサイト・スクリプティングの潜在的な脆弱性対策として有効なブラウザの機能を有効にするレスポンスヘッダを返す。
攻撃例:お問い合わせフォーム
■contact.php
<form action="confirm.php">
<label for="name">名前
<input type="text" name="name" id="name">
<label for="mail">メール
<input type="email" name="mail" id="mail">
</form>
■confirm.php
<form action="thanks.php">
<label for="name">名前
<input type="text" name="name" id="name" value="<?php echo $_POST['name'] ?>">
<label for="mail">メール
<input type="email" name="mail" id="mail" value="<?php echo $_POST['name'] ?>">
</form>
上記の例では、入力フォームにJavaScriptのスクリプトを仕込むことが可能です。
confirm.phpの$_POST['name']のあたいが「" onmouseover="alert('hacked!')"」のようにすると、
valueは空になり、スクリプト実行可能な状態になってしまうからです。
ここに悪意のあるスクリプト実行を仕込めば個人情報漏洩などにつながります。
この場合の対策は、エスケープ処理です。
HTMLへの出力は「htmlspecialcharset関数」などを用いて、スクリプトとして認識されないただの文字列に変換することでリスク回避できます。
保険としてCookie情報を送れないようにHttpOnly属性を加えましょう。
■.htaccess
php_flag session.cookie_httponly On
クロスサイトリクエストフォージェリ
ウェブサイトの中には、サービスの提供に際しログイン機能を設けているものがあります。ここで、ログインした利用者からのリクエストについて、その利用者が意図したリクエストであるかどうかを識別する仕組みを持たないウェブサイトは、外部サイトを経由した悪意のあるリクエストを受け入れてしまう場合があ ります。このようなウェブサイトにログインした利用者は、悪意のある人が用意した罠により、利用者が予期しない処理を実行させられてしまう可能性があります。このような問題を「CSRF(Cross-Site RequestForgeries/クロスサイト・リクエスト・フォージェリ)の脆弱性」と呼び、これを悪用した攻撃を、「CSRF 攻撃」と呼びます。
引用元:IPA「安全なウェブサイトの作り方(改訂第7版)P30」
対策:
・処理を実行するページを POST メソッドでアクセスするようにし、その「hidden パラメータ」に秘密情報(トークン)が挿入されるよう、前のページで自動生成して、実行ページではその値が正しい場合のみ処理を実行する。
・処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。
・Refererが正しいリンク元かを確認し、正しい場合のみ処理を実行する。
・重要な操作を行った際に、その旨を登録済みのメールアドレスに自動送信する。
攻撃例:
こちらは分かりやすいPoC付きの事例がありましたのでそちらをご参照ください。
https://teratail.com/questions/71592
クリックジャッキング
ウェブサイトの中には、ログイン機能を設け、ログインしている利用者のみが使用可能な機能を提供しているものがあります。該当する機能がマウス操作のみで使用可能な場合、細工された外部サイトを閲覧し操作することにより、利用者が誤操作し、意図しない機能を実行させられる可能性があります。このような問題を「クリックジャッキングの脆弱性」と呼び、問題を悪用した攻撃を、「クリックジャッキング攻撃」と呼びます。
引用元:IPA「安全なウェブサイトの作り方(改訂第7版)P41」
対策:
・HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限する。
⇒.htaccessに「Header always append X-Frame-Options SAMEORIGIN」などを挿入する
・処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。
・重要な処理は、一連の操作をマウスのみで実行できないようにする。
攻撃例:
視覚的な問題なので画像にて説明します。
クリックジャッキングは下記のように、ダミーサイトでクリックしたくなるような部分に
攻撃対象のサイトを設置してなんらかのクリック操作をさせるものです。
下記ではECサイトで自分の想定しない購入をしてしまうことになります。
セキュリティチェックツール(OWASP ZAP)について
ほかに、HTTPヘッダインジェクション、HTTPレスポンス分割攻撃、NULLバイト攻撃、Emailヘッダインジェクションなどがありますので
是非調べてみてください。
自分なりの説明ができるか、例をコードで示すことができればある程度理解しています。
また、WEBアプリケーションの脆弱性診断ツールというものがあります。
そちらを利用することで自分の予期していなかった脆弱性に気づくこともでき、
知らなかった脆弱性のキャッチアップにもつながることが期待できます。
私は「OWASP ZAP」というツールを使用しています。
詳しくは公式サイトを確認してみてください。
読み方は「オワスプ」。正式には「Open Web Application Security Project(国際ウェブセキュリティ標準機構)」の略であり、組織名です。
OSSですので無料で使用可能です。
最後に
ソフトウェアによって、便利さが加速する反面でセキュリティのインシデントも増えています。
お客様の事業拡大の攻めを担うWEBサイトでも、問い合わせフォームなどは特に、個人情報を取り扱う窓口になるため慎重になるべきポイントです。
気軽にWEBサイトを構築できるようになった今であるからこそ、守りの部分にも目を向けてもらえたら幸いです。
また、世の中で「まずググれ」と言われるほどには情報発信量も増えているのかなと思います。
情報が増えると、どうしても信頼性が薄くなっていきます。
情報のソースを明確にして、できる限り正しい情報を発信することを今後も目指します。