jeudi 23 janvier 2020

How to know if a SMTP mailbox is a catch-all?

Context

There are services, like https://mailboxlayer.com/ that are able to tell the quality of a real mailbox before sending out any email.

Initially this service checks 3 things:

  • If the MX records exist.
  • If the mailbox exist.
  • If the mailbox is a catch-all.

Problem

I need to programmatically do something similar in PHP.

Investigation

MX records

For the MX records, there's the following PHP function that does the job:

 getmxrr ( string $hostname , array &$mxhosts [, array &$weight ] ) : bool

documented in here: https://www.php.net/manual/en/function.getmxrr.php

Behind scenes, this is a classic DNS search. Here there is a sample session:

ubuntu@ip-177-32-4-56:~$ nslookup -q=mx yahoo.com
Server:         172.30.0.2
Address:        172.30.0.2#53

Non-authoritative answer:
yahoo.com       mail exchanger = 1 mta7.am0.yahoodns.net.
yahoo.com       mail exchanger = 1 mta5.am0.yahoodns.net.
yahoo.com       mail exchanger = 1 mta6.am0.yahoodns.net.

Authoritative answers can be found from:

ubuntu@ip-177-32-4-56:~$

Mailbox exists

For the existance of the mailbox, what we have already implemented is a telnet connection to the SMTP server, send a EHLO command, send a "from", and then send a "to".

As a reference, see this article: https://www.webdigi.co.uk/blog/2009/how-to-check-if-an-email-address-exists-without-sending-an-email/

If the username does not exist, most SMTP servers respond with a 5xx error. If it exists and responds with a 2xx code, it does not mean you'll succeed in sending the email (maybe there's quota full or whatever, but you substantially reduce chances of sending silly emails).

Mailbox is a catch-all

But not all the SMTP servers respond a 5xx on user not existing. Some, like yahoo, will make their SMTP to accept mail to any random address... try to telnet to port 25 and send something to my-very-nice-invented-username-with-random-data-58943758346758923467894@yahoo.com and it will tell you 2xx.

Here's a sample session:

ubuntu@ip-177-32-4-56:~$ telnet mta7.am0.yahoodns.net 25
Trying 67.195.204.72...
Connected to mta7.am0.yahoodns.net.
Escape character is '^]'.
220 mtaproxy303.free.mail.bf1.yahoo.com ESMTP ready
EHLO hi
250-mtaproxy303.free.mail.bf1.yahoo.com
250-PIPELINING
250-SIZE 41943040
250-8BITMIME
250 STARTTLS
mail from:<alice@example.com>
250 sender <alice@example.com> ok
rcpt to:<stupid-address-758346758347587859023475890234758902@yahoo.com>
250 recipient <stupid-address-758346758347587859023475890234758902@yahoo.com> ok
quit
221 mta4014.mail.bf1.yahoo.com
Connection closed by foreign host.
ubuntu@ip-177-32-4-56:~$

Possible solution

To emulate the behaviour of mailboxlayer.com to check for a catch-all, the most I can think is to make a double test: Test the expected address, and then test the same MX by creating a random string like for example a sha1.

If I test e07cf4a93e76ce21eb1f76e1a49e1620f767eb5a@yahoo.com and it says "yes" then mark yahoo.com as a catch-all domain.

Question

I wonder if there's a more canonical and clean way of doing this other than the exposed idea.

Aucun commentaire:

Enregistrer un commentaire