質問: 現在予約サイトのセキュリティ見直しをしています。 社内に自分以外システム担当がおらず、自分もまだまだ勉強不足経験不足なため、幼稚な質問でしたら申し訳ございません。 ~~<機能> 1.一般のユーザが予約フォームに氏名、住所、電話番号等の個人情報と、予約希望日時を入れる 2.確定ボタンを押すと、一般ユーザ、予約された店舗、弊社の管理者アドレスの3カ所に予約された旨を告げるメールが送られる 3.2と同時に、システム内で予約を行なったユーザの入力内容を弊社のDBに登録する~~ <言語、関数> PHP7 mb_send_mail() <質問> 2.で送信先アドレスや、メール本文に1.でユーザが入力した内容を用いますが、エスケープされていません。 POSTで受け取った内容をそのままメールの宛先アドレスや、メール本文に使っています。 途中エンコードしているところはありますが、エスケープはされていません。 これはセキュリティ的には問題ないのでしょうか? (第三者のアドレスが勝手に挿入されて勝手にメールを受信されたり、メール本文に勝手に不正なスクリプトなどを入れられたりしないのでしょうか?) ちなみに、3.でユーザ情報をDBに登録する際にはエスケープしてからINSERTしています。 追記1: <機能> 1.ユーザが個人情報、希望日時を入力すし、「確認画面へ」ボタンを押す 2.バリデーションチェックを行い、不正なら入力画面へ戻る。 正常なら入力内容確認画面を表示する 3.入力内容確認画面で確定ボタンを押すと、一般ユーザ、予約された店舗、弊社の管理者アドレスの3カ所に予約された旨を告げるメールが送られる 4.4と同時に、システム内で予約を行なったユーザの入力内容を弊社のDBに登録する 追記2: 送信するメールはテキストメール 追記3: 確認画面に遷移するタイミングでバリデーションチェックしてれば、Toに第三者の予期しないアドレスが入れられてしまうことはないですか? よろしくお願いいたします。
回答: > > 確認画面に遷移するタイミングでバリデーションチェックしてれば、Toに第三者の予期しないアドレスが入れられてしまうことはないですか? > > > 2つの観点があります。 まず、確認画面でバリデーションしても、その値をhiddenで引き回している場合は、送信画面へのリクエストを操作して不正なメールアドレスを指定される可能性があります。同じバリデーションを送信画面でも行うことで対策になります。 もう一つは、こちらの方が問題ですが、例えば悪い人が私のメールアドレスを知っていたとして、悪人がそのフォームで私のメールアドレスを入力することはできてしまいます。これは防ぐことが難しい問題ですが、「第三者の予期しないアドレス」をどう定義するのかという問題でもあります。一般的には、第三者のメールアドレスが指定できる事自体は許容してしまい、悪用されても大事に至らないようにメール本文側を工夫する(悪用の余地が少ないようにする)ことが多いです。 コメントに対する回答を追記します。 > > 1つ目の観点に関しては、hiddenは使っていないのですが、それでも送信画面で再度バリデーションした方がよろしいでしょうか? > > > バリデーションするという考え方もありますが、通常はしないと思います。バリデーションしないことによる直接の問題はありません。 > > 確認画面でバリデーションしてても送信画面を表示、確認ボタン(メール送信)押下の段階で攻撃者に不正なアドレス入れられたりするのだろうか?と。。 > > > おそらくメールアドレス等をセッション変数に格納しているのだと思いますので、以下その前提で回答します。 ウェブアプリケーションに脆弱性があれば起こりえます。主にクロスサイトスクリプティング(XSS)脆弱性がある場合にそのような(あるいは類似の)現象が起きる可能性があります。 > > 2つ目の観点に関しては、自分的には「第三者の予期しないアドレス」は、正規の手順で正規の目的のため(店舗に予約する)弊社サイトで予約を行なったユーザの予約確認メール(個人情報記載)が実は予期せず攻撃者のアドレスにも送られてしまうのではないかと考えていました。 > > > これはクロスサイトスクリプティング(XSS)脆弱性がある場合は起こりえます。ただし、アプリケーションの作りにもよりますが、メールアドレスだけ差し替えることは通常難しく、問い合わせ内容なども含めて上書きすることになるので、メールアドレスを差し替えることによる情報漏えいは起きにくいかと思います。むしろ、クロスサイトスクリプティングそのものを使った情報漏えいの方が可能性が高いです。 クロスサイトスクリプティングがある(かもしれない)という前提では、情報をセッション変数で受け渡すよりも、hiddenパラメータで渡した方が攻撃はしにくくなります。セッション変数は情報をサーバー側で覚えているので、その覚えている情報が漏れる可能性があるのに対して、hiddenパラメータの場合は情報を覚えているのはブラウザであり、サーバー側の情報は保持されない(処理が終われば直ちに消える)からです。 クロスサイトスクリプティング脆弱性をなくすことが本筋ではありますが、上記に対する緩和策としては、用済みのセッション変数は直ちに削除することや、セッションタイムアウトを短くすることが考えられます。 > > ockeghemさんが例でおっしゃってくださったパターンだと、よく会員制サイトのパスワード変更などをしてパスワード変更完了を告げるメールが届いたときに記載してある「このメールに覚えがない場合は下記URLまでご連絡ください」といった文言があるもののことでしょうか? > > > これは直接関係ありません。このメールの意図は、攻撃者がなりすましでパスワードを変更した場合に、「パスワードが変更された」旨を利用者に通知し、利用者が意図したパスワード変更かどうかを確認してもらうためです。なので、メール送信自体は、セキュリティ強化の意図によるもので、このメールにより情報を盗むとか詐欺行為をしたいわけではありません。