正規表現等によるメールアドレスの形式確認をサーバーサイドで行う必要はない

先日、SNSで次のエントリを見かけました。

正規表現でのメールアドレスチェックは見直すべき – ReDoS

ある種の正規表現をサーバー上で実行したときに、DoS攻撃に繋がるおそれがあるという指摘です。 ところで、そもそもメールアドレスの形式チェックはなんのために行うのでしょうか?

ユーザーの正しいメールアドレスが muto@example.com のケースを考えます。

もしもユーザーが入力したメールアドレスが、mutoexample.com のように@マークが含まれないなど不正な形式であった場合、当然ながらユーザーのもとにメールは届きません。このようなミスは、たしかに正規表現等による簡単な形式チェックで防げるでしょう。

一方、たとえば、 nuto@example.com と入力してしまうような入力ミスは、形式的に不正ではないため正規表現では防げません。つまり、正規表現では、ユーザーの入力ミスによってメールが届かないケースを完全に防ぐことはできません。

しかしながら、メールアドレスをユーザーIDとして使用するようなサービスであれば、ユーザーが入力を間違えたままにはなることはありません。一般的に、登録されたメールアドレスに対してトークン付きのURLが記載されたメールを送信し、ユーザーがそのURLにアクセスすることで、はじめて登録完了となるからです。1

いずれにせよ誤ったメールアドレスが入力され得るのであれば、メールアドレスの形式チェックは不要なのでしょうか?必ずしもそうとは言えません。ユーザーの元にメールが 到達しないまで 何のフィードバックも与えないよりは、誤りが確認できた段階でフィードバックを返すほうがユーザーインターフェイスとして優れているからです。

しかし、ユーザーインターフェイスの改善を目的としたメールアドレスのチェックであれば、サーバーサイドよりも適した場所があります。クライアントサイドです。HTML5であれば、 input タグに type=email として指定すれば形式チェックが行われますし、正規表現で簡単な形式確認を行っても良いでしょう。クライアントサイドであれば、例え重い正規表現を実行してもDoS攻撃になることはありません。ユーザーにもより速くフィードバックを返すことができユーザーインターフェイスとしても優れています。

もちろん、直接HTTPリクエストを送信するなどして、あえて形式チェックを通さずにリクエストを送信することは可能ですが、通常サービス側で用意したユーザーインターフェイスを使用していれば起きないことなので、このケースは無視して良いでしょう。

したがって、サーバーサイドでのメールアドレスチェックは、入力有無や長さ確認など、メールアドレス以外のテキストフィールドと同様の処理を行えば十分であり、ユーザーインターフェイスの改善を目的とした形式チェックはクライアントサイドのみで行えば十分です。

  1. ユーザーIDとしては使用せず、連絡用などとして到達確認を必須としないケースでは、誤ったメールアドレスが登録されたままになることもありえます。