メールヘッダーと本文のインジェクション

メールヘッダーと本文のインジェクション

説明

メールヘッダーへユーザー入力をそのまま連結すると、CR/LFで新たなヘッダーや本文を挿入されるおそれがあります。パスワード再設定リンクや取引メールの本文を、信頼できないURL・ホストの値で組み立てた場合も、攻撃者に内容を変更される可能性があります。

想定される影響

  • フィッシングリンクの挿入や、パスワード再設定フローの悪用につながるおそれがあります。
  • ユーザーが改ざんされたメールを正規サービスからの通知だと誤認する可能性があります。

対処方法

  • メールの基準URLとホスト名は信頼できるサーバー設定から取得し、再設定トークンもサーバーで生成してください。
  • ヘッダー値のCR/LFを拒否し、宛先アドレスの形式と業務上の許可範囲を検証してください。HTML本文のテキストやリンクには、それぞれの出力文脈に合う処理を適用してください。
  • SMTPの宛先と表示用のメッセージヘッダーを区別し、正しい受信者を指定してください。

例

To ヘッダーの組み立て方だけを比較する抜粋です。smtp.SendMail の実際のSMTP宛先は、別の to 引数で決まります。認証、転送の保護、送信エラーの処理は省略しています。変更後の固定アドレスは、実際に承認された宛先に置き換えてください。

変更前

go
email := r.FormValue("email")
body := "Subject: reset\r\nTo: " + email + "\r\n\r\nhello"
smtp.SendMail(addr, nil, from, to, []byte(body))

変更後

go
body := "Subject: reset\r\nTo: user@example.com\r\n\r\nhello"
smtp.SendMail(addr, nil, from, to, []byte(body))

解説:

  • 変更前: 未検証の email を To ヘッダーへ連結するため、CR/LFを含む入力がヘッダーや本文を変更する可能性があります。
  • 変更後: この例の To ヘッダーはユーザー入力から作りません。動的な宛先にも検証が必要で、再設定URLの信頼性は別途確保する必要があります。

参考資料