質問: Gmail ではメールアドレスに `+` 記号を付けることでひとつのアカウントのメールアドレスにタグを付けて扱うことができます。しかしたとえばユーザー登録時のメールアドレスに `+` 記号が含まれていると「正しいアドレスを入力してください」とバリデーションエラーを出すウェブアプリにしばしば遭遇します。 RFC 5322 によると、メールアドレスのローカルパートには記号 `!#$%&'*+-/=?^_`{|}~` を含むことができます。なのでバリデーション側が間違っていることになります。 ただもしかすると、メールアドレスの仕様では OK でも、裏側で動いているシステムにおいて NG なことがあるのかもしれません。たとえば何かしらセキュリティリスクがあって許しておらず、そのエラーメッセージがたまたま「アドレスが間違っている」というものになっているのかもしれません。もしそうなのであれば自分でアプリを作る際に注意しておきたいです。逆に、単に歴史的理由や特定のライブラリのバグなのであれば気にする必要が無くなります。 そこで、質問です。メールアドレス内に記号(特に `+`)を許すことによるリスクはありますか? あるならば、どのようなものでしょうか? それは適切なエスケープを課すなどして避けられないものなのでしょうか?
回答: どの場面で許すかによって回答は変わってきます。 sendmailやpostfix は、その設定によって `+` 記号によるタグ付けを許容するかスイッチすることができます。あなたがタグ付けが可能なメールサーバーを運営しているなら、`+` 記号のついたメールアドレスを新規ユーザーアカウントとして認めたいとは思わないでしょう。 `john@example.com` がすでにユーザーとして存在するのに `john+tag@example.com` を別のユーザーに割り当てれば混乱が生じるのは明らかです。 バーチャルドメインを使って一つのメールサーバーに複数のドメインを持たせ、それをMySQLで管理したとします。たとえばこのような設定例に従ってpostfixのセットアップを行った場合、メールアドレスを実際にサーバーのディレクトリ構成にコンバージョンするクエリがRFCに準拠せず、やっつけの `SUBSTRING_INDEX` で端折っているのが分かります。 ``` user = mail_admin password = mail_admin_password dbname = mail table = users select_field = CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') where_field = email hosts = 127.0.0.1 ``` `"@@@@@@"@example.com` は完全にRFCに準拠した「正しい」メールアドレスですが、上のクエリがこのアドレスを正しく解釈できるわけがありません。正しく解釈するにはエスケープではなく適切なパースをやる必要があるのですが、MySQLのクエリ上でそれを実装するのが割に合うかは疑問です。 かつて日本の一部のケータイキャリアはRFC822に準拠しないメールアドレスを登録することが可能でした。ケータイ同士で送受信できれば事足りる多くのユーザーがこれを逆手に取って、スパムメールを遠ざける為にわざとRFC違反のアドレスを登録していたと記憶しています。(ソースが見つかりませんでした。もしあれば追記お願いします。) `john.@example.com` は完全にRFCに準拠していない「不正な」メールアドレスですが、ユーザーはPCから送信されたスパムメールがリレーサーバー上でエラーになることを期待して、あるいはこのようなアドレスがスパム避けになるという話を聞いて、こぞって使われました。これはもちろん、大問題になりました。 RFCは単なるフォーマット仕様であり、サービスのリスクとフォーマット仕様は直接関係しているわけではありません。リスクに見合うメリットがあれば事業者はフォーマット仕様でも破ります。メールのような相手の居るシステムの場合は特にそうです。 自分が送信するときはできる限り素直に送るようにし、逆に受信するときは寛容に構える事がリスクを回避するコツだと思います。 ちなみにローカルパートの `+` 記号の利用は `拡張メールアドレス`/`plus addressing`/`sub-addressing` などと呼ばれ、実はかなり歴史があり、古くは sendmail 8.7 の頃に実装されていた事が当時の RELEASE NOTE や README から読み取れます。Gmailはその伝統に則っているだけで、他のサービスで利用できるかまでは担保していません。これもリスクの一つと言えるかもしれません。 ``` 8.7.1/8.7.1 95/10/01 ... CONFIG: Allow "user+detail" to be aliased specially: it will first look for an alias for "user+detail", then for "user+*", and finally for "user". This is intended for forwarding mail for system aliases such as root and postmaster to a centralized hub. ``` ``` The local mailer accepts addresses of the form "user+detail", where the "+detail" is not used for mailbox matching but is available to certain local mail programs (in particular, see FEATURE(local_procmail)). For example, "eric", "eric+sendmail", and "eric+sww" all indicate the same user, but additional arguments , "sendmail", and "sww" may be provided for use in sorting mail. ```