WebVulnerabilities

メールヘッダインジェクション攻撃について

概要

メールヘッダインジェクション攻撃は、攻撃者が電子メールのヘッダーに改行コード(\r\n)を挿入することで、追加のヘッダーやメッセージ本文を不正に追加する攻撃です。この攻撃により、攻撃者はスパムメールの送信やフィッシング攻撃の実行、メールの内容を改ざんすることが可能になります。メール送信機能がユーザー入力に依存している場合、特にこの脆弱性が発生しやすくなります。


脆弱性を持つコードの例と攻撃手法

PHP

脆弱なコード例:

<?php
$to = $_POST['to'];
$subject = $_POST['subject'];
$message = $_POST['message'];
$headers = "From: webmaster@example.com";

mail($to, $subject, $message, $headers);
?>

攻撃手法:

Python(Flask)

脆弱なコード例:

from flask import Flask, request
import smtplib

app = Flask(__name__)

@app.route('/sendmail', methods=['POST'])
def send_mail():
    to = request.form['to']
    subject = request.form['subject']
    message = request.form['message']
    headers = f"From: webmaster@example.com\nSubject: {subject}\n"

    server = smtplib.SMTP('localhost')
    server.sendmail("webmaster@example.com", to, headers + "\n" + message)
    server.quit()
    return "Mail sent!"

攻撃手法:

Node.js(Express)

脆弱なコード例:

const express = require('express');
const nodemailer = require('nodemailer');
const app = express();

app.use(express.urlencoded({ extended: true }));

app.post('/sendmail', (req, res) => {
    let transporter = nodemailer.createTransport({
        service: 'Gmail',
        auth: {
            user: 'webmaster@example.com',
            pass: 'password'
        }
    });

    let mailOptions = {
        from: 'webmaster@example.com',
        to: req.body.to,
        subject: req.body.subject,
        text: req.body.message
    };

    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            return res.status(500).send(error.toString());
        }
        res.send('Mail sent: ' + info.response);
    });
});

app.listen(3000);

攻撃手法:

Java(Spring Boot)

脆弱なコード例:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;

@RestController
public class MailController {

    private final JavaMailSender mailSender;

    public MailController(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    @PostMapping("/sendmail")
    public String sendMail(@RequestParam String to, @RequestParam String subject, @RequestParam String message) {
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setTo(to);
        mailMessage.setSubject(subject);
        mailMessage.setText(message);
        mailMessage.setFrom("webmaster@example.com");

        mailSender.send(mailMessage);
        return "Mail sent!";
    }
}

攻撃手法:


防止策

  1. 改行コードの除去:
    • ユーザー入力から改行コード(\r\n)を除去し、複数のヘッダーが注入されるのを防ぎます。

    PHPの例:

    $to = str_replace(array("\r", "\n"), '', $_POST['to']);
    $subject = str_replace(array("\r", "\n"), '', $_POST['subject']);
    

    Python(Flask)の例:

    to = request.form['to'].replace('\r', '').replace('\n', '')
    subject = request.form['subject'].replace('\r', '').replace('\n', '')
    

    Node.js(Express)の例:

    let to = req.body.to.replace(/(\r\n|\n|\r)/gm, "");
    

    Java(Spring Boot)の例:

    to = to.replaceAll("[\r\n]", "");
    subject = subject.replaceAll("[\r\n]", "");
    
  2. メール送信ライブラリの使用:
    • 標準的なメール送信ライブラリを使用し、ヘッダーインジェクションのリスクが低い安全な方法でメールを送信します。
  3. ホワイトリスト方式の適用:
    • メールアドレスやヘッダーの内容を検証し、特定の形式のみを許可するホワイトリスト方式を採用します。
  4. セキュリティテストの実施:
    • メール送信機能に対して定期的にセキュリティテストを実施し、ヘッダーインジェクションの脆弱性がないか確認します。

まとめ: メールヘッダインジェクション攻撃は、電子メールのヘッダーに不正なデータを注入することで、スパムメールの送信やフィッシング攻撃を可能にする危険な攻撃です。ユーザー入力のエスケープや改行コードの除去、ホワイトリスト方式の適用などの防止策を講じることで、この脆弱性を防ぐことが可能です。