質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.04%

予約システムのセキュリティについて(予約完了メールにエスケープ無しで入力値を入れることについての是非)

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 606

ringoman

score 6

現在予約サイトのセキュリティ見直しをしています。
社内に自分以外システム担当がおらず、自分もまだまだ勉強不足経験不足なため、幼稚な質問でしたら申し訳ございません。

<機能> 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に第三者の予期しないアドレスが入れられてしまうことはないですか?

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ringoman

    2019/09/19 16:04

    >m.ts10806さん
    追記したのですが、確認画面に遷移するタイミングでバリデーションチェックしてれば、Toに第三者の予期しないアドレスが入れられてしまうことはないですか?
    Fromはコード内で直打ちしており、CcとBccは不使用なため、この3つは問題ないかと思っています。
    他の方からの回答で、テキストメールであればスクリプト埋め込まれる心配もないかと思っています。

    キャンセル

  • m.ts10806

    2019/09/19 16:19

    「メールアドレスとして正しい形式か」はチェックできても「その人のメールアドレスとして正しいか」はチェックできませんよ。入力者の自己責任です。
    「不正なアドレスを防ぐエスケープ」と表現されていたので「それエスケープちゃう、バリデーションや」と突っ込みたかったのです。

    キャンセル

  • ringoman

    2019/09/20 13:56

    >m.ts1086さん
    不正なアドレスの表現が悪かったです。
    おかげでバリデーションとエスケープの違いを改めて勉強できました。
    突っ込みありがとうございます。

    キャンセル

回答 5

checkベストアンサー

+6

確認画面に遷移するタイミングでバリデーションチェックしてれば、Toに第三者の予期しないアドレスが入れられてしまうことはないですか?

2つの観点があります。
まず、確認画面でバリデーションしても、その値をhiddenで引き回している場合は、送信画面へのリクエストを操作して不正なメールアドレスを指定される可能性があります。同じバリデーションを送信画面でも行うことで対策になります。
もう一つは、こちらの方が問題ですが、例えば悪い人が私のメールアドレスを知っていたとして、悪人がそのフォームで私のメールアドレスを入力することはできてしまいます。これは防ぐことが難しい問題ですが、「第三者の予期しないアドレス」をどう定義するのかという問題でもあります。一般的には、第三者のメールアドレスが指定できる事自体は許容してしまい、悪用されても大事に至らないようにメール本文側を工夫する(悪用の余地が少ないようにする)ことが多いです。


コメントに対する回答を追記します。

1つ目の観点に関しては、hiddenは使っていないのですが、それでも送信画面で再度バリデーションした方がよろしいでしょうか?

バリデーションするという考え方もありますが、通常はしないと思います。バリデーションしないことによる直接の問題はありません。

確認画面でバリデーションしてても送信画面を表示、確認ボタン(メール送信)押下の段階で攻撃者に不正なアドレス入れられたりするのだろうか?と。。

おそらくメールアドレス等をセッション変数に格納しているのだと思いますので、以下その前提で回答します。
ウェブアプリケーションに脆弱性があれば起こりえます。主にクロスサイトスクリプティング(XSS)脆弱性がある場合にそのような(あるいは類似の)現象が起きる可能性があります。

2つ目の観点に関しては、自分的には「第三者の予期しないアドレス」は、正規の手順で正規の目的のため(店舗に予約する)弊社サイトで予約を行なったユーザの予約確認メール(個人情報記載)が実は予期せず攻撃者のアドレスにも送られてしまうのではないかと考えていました。

これはクロスサイトスクリプティング(XSS)脆弱性がある場合は起こりえます。ただし、アプリケーションの作りにもよりますが、メールアドレスだけ差し替えることは通常難しく、問い合わせ内容なども含めて上書きすることになるので、メールアドレスを差し替えることによる情報漏えいは起きにくいかと思います。むしろ、クロスサイトスクリプティングそのものを使った情報漏えいの方が可能性が高いです。
クロスサイトスクリプティングがある(かもしれない)という前提では、情報をセッション変数で受け渡すよりも、hiddenパラメータで渡した方が攻撃はしにくくなります。セッション変数は情報をサーバー側で覚えているので、その覚えている情報が漏れる可能性があるのに対して、hiddenパラメータの場合は情報を覚えているのはブラウザであり、サーバー側の情報は保持されない(処理が終われば直ちに消える)からです。
クロスサイトスクリプティング脆弱性をなくすことが本筋ではありますが、上記に対する緩和策としては、用済みのセッション変数は直ちに削除することや、セッションタイムアウトを短くすることが考えられます。

ockeghemさんが例でおっしゃってくださったパターンだと、よく会員制サイトのパスワード変更などをしてパスワード変更完了を告げるメールが届いたときに記載してある「このメールに覚えがない場合は下記URLまでご連絡ください」といった文言があるもののことでしょうか?

これは直接関係ありません。このメールの意図は、攻撃者がなりすましでパスワードを変更した場合に、「パスワードが変更された」旨を利用者に通知し、利用者が意図したパスワード変更かどうかを確認してもらうためです。なので、メール送信自体は、セキュリティ強化の意図によるもので、このメールにより情報を盗むとか詐欺行為をしたいわけではありません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/20 13:23

    回答ありがとうございます。
    1つ目の観点に関しては、hiddenは使っていないのですが、それでも送信画面で再度バリデーションした方がよろしいでしょうか?
    どちらかというと自分的には1つ目の観点を心配しておりました。
    確認画面でバリデーションしてても送信画面を表示、確認ボタン(メール送信)押下の段階で攻撃者に不正なアドレス入れられたりするのだろうか?と。。
    2つ目の観点に関しては、自分的には「第三者の予期しないアドレス」は、正規の手順で正規の目的のため(店舗に予約する)弊社サイトで予約を行なったユーザの予約確認メール(個人情報記載)が実は予期せず攻撃者のアドレスにも送られてしまうのではないかと考えていました。
    そういう意味で「第三者の予期しないアドレス」と表現していました。
    ockeghemさんが例でおっしゃってくださったパターンだと、よく会員制サイトのパスワード変更などをしてパスワード変更完了を告げるメールが届いたときに記載してある「このメールに覚えがない場合は下記URLまでご連絡ください」といった文言があるもののことでしょうか?

    キャンセル

  • 2019/09/24 12:28

    丁寧に回答していただき、ありがとうございます。
    おかげさまで見直すべきはメールがどうとかよりクロスサイトスプリクティング対策の観点だということがわかりました。
    大変助かりました。

    キャンセル

+1

第三者のアドレスが勝手に挿入されて勝手にメールを受信されたり、メール本文に勝手に不正なスクリプトなどを入れられたりしないのでしょうか?

mb_send_mailを使って書く限り、fromは適切なものに制限されますし、テキスト形式のメールであれば、不正なスクリプトが入ってもただメール本文になるだけです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/19 13:24

    fromをadditional_headers(mb_send_mailの第4引数)に文字列として渡す場合は、メールヘッダ・インジェクションの可能性があります(配列で渡す場合は問題ないがPHP7.2以降の機能)が、今回の仕様だと、fromではなく、toに外部入力を指定することになりそうで、その場合は問題ないと思います。

    キャンセル

  • 2019/09/19 14:39

    >maisumakunさん
    回答ありがとうございます。
    メールの本文的にはhtmlタグは入っていないのでテキストメールかと思うのですが、メールの本文にhtmlタグ入っていないからテキストメールであると判断してしまってよろしいんでしょうか?
    それともこの関数使ってればテキストメールとか、この設定を行なっていればテキストメールとか明確にテキストメールかhtmlメールか判別できるようなものがありますか?

    キャンセル

  • 2019/09/24 12:32

    >maisumakunさん
    回答ありがとうございます。
    本件はテキストメールであると判明したので、メール本文になるだけとのことで安心しました。
    大変助かりました。

    キャンセル

+1

POSTで受け取った内容をそのままメールの宛先アドレスや、メール本文に使っています。途中エンコードしているところはありますが、エスケープはされていません。
これはセキュリティ的には問題ないのでしょうか?

コード無いので適当な回答ですが、問題あります。
記述そのままであれば、スパムの発射台として使用できるかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/20 13:43

    追記したのですが、入力画面で入力した後「確認画面へボタン」があり、これを押下するとバリデーションチェックが走り、形式が不正なら入力画面へ戻り、正常なら確認画面を表示します。
    確認画面に「予約確定ボタン」があり、これを押すと、メール送信、DB登録の処理が走ります。
    会社のコードなのでなるべくコードは公開したくないのですが、特にどの段階で誰のアドレスがスパムの発射台にされそうかご教授いただけませんか?
    ユーザアドレスは入力画面でユーザが入力し、宛先アドレスとメール本文へバリデーション有エスケープ無しで使用されます。
    店舗アドレスは弊社DBから取得し、宛先アドレスとメール本文にエスケープ無しで使われます。
    管理者アドレスはコード内で直打ちしています。
    スパム発射台について調べたのですが、メールアカウントのパスワード管理不足によるアカウント乗っ取りしか出てきませんでした。。。

    キャンセル

  • 2019/09/20 14:24

    > 特にどの段階で誰のアドレスがスパムの発射台にされそうかご教授いただけませんか?

    すでに回答しています。

    指針がないから悩むし、相談が要領をえません。コードも無いし。。。
    セキュリティ要件の整理と設計からしてみては?

    キャンセル

  • 2019/09/20 14:27

    わかりました。
    ありがとうございます。

    キャンセル

0

HTMLメールでなければ大丈夫だとは思いますが
HTMLは本来7bitJISエンコードするものなので基礎だけ抑えて置く必要はあります

予約システムとリンクしているなら
HTMLは登録されたことだけを知らせるアラートとして使えばよいような気もします

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/20 13:57

    本件はテキストメールであるということが発覚しました。
    回答ありがとうございます。
    助かりました。

    キャンセル

0

とにもかくにもJavaScript(一部を除く)やPHPは入力値をエスケープをするのが安全かと。

te2jiさんからご指摘いただきましたがこの場合はバリデーション(入力値検証)でした。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/19 13:14

    本件だと、エスケープと言うよりは、バリデーションの問題かと。

    キャンセル

  • 2019/09/19 13:30 編集

    そうですね、バリデーションでした。
    (普段あんまり人に向けて説明しないので自分自身混同してました)

    キャンセル

  • 2019/09/24 12:29

    回答ありがとうございます。
    再度バリデーションとエスケープの違いについて勉強することができました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • PHPに関する質問
  • 予約システムのセキュリティについて(予約完了メールにエスケープ無しで入力値を入れることについての是非)