メールの誤送信を防止するには下記のような手段が考えられる。
- サーバ側で対応する。
Postfixのsmtpd_client_restrictionsなど。 - クライアント側で対応する。
Thunderbirdのcheck and sendなど。
https://addons.mozilla.org/ja/thunderbird/addon/check-and-send/ - サーバ-クライアント間で対応する。
SMTPのProxyを使ってチェックする、AntiVirusっぽくクライアントのOSレイヤーで通信をチェックする、DeepInspection的にパケットの転送経路で通信をチェックする。などなど。
なんとなく、3.の一番目「SMTPのProxyを使って対応する」が可能かコードを書いてみた。結果はページの最後に。PerlのCPANは非常に便利で簡単に書ける。(ただし、テストはあまりしていないので信頼性などは微妙。ここはproof-of-conceptの場所なのでその辺りはつっこまないでください。)
なお、下記のコードは悪意のある人がいる状況下で一定の人にしかメールを送らせないための対応としては使ってはいけない。
なぜなら、RFCで許されるメールアドレスのチェックは難しく、一定文字列が含まれる場合は許可というルールは危険すぎるからである。
http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9
メールアドレスチェックが難しい理由としては、メールの不正中継をテストするテストパターンも参考になる。(%による転送経路指定とか。)
http://www.atmarkit.co.jp/fsecurity/rensai/securitytips/005checkmail.html
以下、Perlのコード。
use Carp;
use Net::SMTP::Server;
use Net::SMTP::Server::Client;
use Net::SMTP::Server::Relay;
use Data::Dumper;
my $SMTP_SERVER = "smtp_server";
my $SMTP_PORT = "587";
#メールあて先チェック用
sub is_ok_to{
my $ref_to_ary = shift;
foreach my $to (@$ref_to_ary) {
#あて先チェックをここに書く。
if($to !~ /[email protected]/){
return 0;
}
}
return 1;
}
# 以下本体処理部分
#CPANより。
#http://search.cpan.org/~macgyver/SMTP-Server-1.1/Server.pm
$server = new Net::SMTP::Server('localhost', 25) ||
croak("Unable to handle client connection: $!n");
while($conn = $server->accept()) {
my $client = new Net::SMTP::Server::Client($conn) ||
croak("Unable to handle client connection: $!n");
$client->process || next;
#ここまでCPANのサンプルコード(コメントは削除)
if(is_ok_to($client->{TO})){
&send_mail($client->{FROM},$client->{TO},$client->{MSG});
}else{
print "bad mail [" . Dumper($client). "]";
}
}
#問題の無いメールを送る
sub send_mail{
my $from = shift;
my $ref_to_ary = shift;
my $msg = shift;
$smtp = Net::SMTP->new($SMTP_SERVER, Port=>$SMTP_PORT );
$smtp->mail($from);
foreach my $to (@$ref_to_ary) {
$smtp->to($to);
}
$smtp->data($msg);
$smtp->quit() || croak "send_mail() failed [" . Dumper($from, $ref_to_ary, $msg). "]";
return;
}