• XSS.stack #1 – первый литературный журнал от юзеров форума

Определение валидности списка email (техническая сторона вопроса)

user_47

(L3) cache
Пользователь
Регистрация
25.06.2023
Сообщения
210
Решения
2
Реакции
93
Гарант сделки
2
Всем салют!

Стоит задача делать точечную рассылку по скромному списку компаний (до пяти компаний в неделю). Количество адресов 100-150 писем максимум на один корп. Майлы добываются OSINTом с разных мест. В том числе составлением адресов по известным именам сотрудников и формата построения логина в почтовом адресе.

Возник вопрос определения валидности таких адресов. Понятно что можно шерстить соцсети и вычленять активных сотрудников компании. Также можно воспользоваться специальными ресурсами вроде Hunter.io. Только анализ соц сетей это долго, а ресурсы осинта дают неточный результат. Может конечно я использую неверные сервисы. Пока остановился на результатах выдачи osintframework[.]com Буду рад если кто то поделится дельной ссылко по этому вопросу.

Изучение технической стороны вопроса в первом приближении показало что вся фишка в обращении непосредственно к почтовому серверу. Зная домен, мы спрашиваем у сервера есть ли у него интересующий нас почтовый адрес. Когда тебе надо проверить пяток почт - это нормально. А если на серв прилетает куча запросов с просьбой рассказать про все майлы корпа?)) Такое на мой вгляд может выглядеть подозрительно.

ЧатЖэПэТэ показал такой код на GO:

Код:
package main

import (
    "fmt"
    "net"
    "net/smtp"
    "regexp"
)

// Проверка формата адреса электронной почты
func isValidEmail(email string) bool {
    re := regexp.MustCompile(^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$)
    return re.MatchString(email)
}

// Получение MX-записей для домена
func getMXRecords(domain string) ([]*net.MX, error) {
    return net.LookupMX(domain)
}

// Проверка существования адреса электронной почты
func checkEmail(email string) (bool, error) {
    if !isValidEmail(email) {
        return false, fmt.Errorf("недопустимый формат адреса электронной почты")
    }

    // Разделение адреса на локальную часть и домен
    parts := regexp.MustCompile("@").Split(email, 2)
    if len(parts) != 2 {
        return false, fmt.Errorf("недопустимый формат адреса электронной почты")
    }
    localPart := parts[0]
    domain := parts[1]

    // Получение MX-записей
    mxRecords, err := getMXRecords(domain)
    if err != nil || len(mxRecords) == 0 {
        return false, fmt.Errorf("не удалось получить MX-записи для домена %s", domain)
    }

    // Проверка наличия почтового ящика
    for _, mx := range mxRecords {
        // Установка соединения с SMTP-сервером
        conn, err := smtp.Dial(fmt.Sprintf("%s:%d", mx.Host, 25))
        if err != nil {
            continue // Пропускаем, если не удалось подключиться
        }
        defer conn.Close()

        // Установка идентификатора отправителя
        if err := conn.Mail("test@example.com"); err != nil {
            continue // Пропускаем, если ошибка при установке отправителя
        }

        // Установка получателя
        if err := conn.Rcpt(email); err != nil {
            return false, nil // Если возникла ошибка, адрес не существует
        }

        return true, nil // Если все прошло успешно, адрес существует
    }

    return false, fmt.Errorf("не удалось проверить адрес электронной почты")
}

func main() {
    email := "test@example.com"

    exists, err := checkEmail(email)
    if err != nil {
        fmt.Println("Ошибка:", err)
    } else if exists {
        fmt.Println("Адрес электронной почты существует.")
    } else {
        fmt.Println("Адрес электронной почты не существует.")
    }
}

Тут метод conn.Rcpt(email) как раз и определяет валидность адреса. При работе метода происходит обращение на сервер получателя с вопросом, сможет ли он обработать данные для указанного пользователя. Использование этого метода несколько раз для разных адресов даже не возбраняется.

Правда серв может брехать про валидность адреса, если что то не понравится в запросе:) Думаю поэтому сервисы и дают неточные результаты.

Подведу итог своей писанины.

Не подозрительно ли заваливать серв запросами валидности адресов? Или мои объёмы мизер для хостера типа мелкомягких? Существует ли какой то точный технический метод определения валидности адресов сопоставимый по точности с копанием соцсетей?
 
валидация емейлов - это процесс достаточно простой.
точная валидация возможна рассылкой и сбором кодов ответов.
либо эмуляцией такой рассылки через прокси сервера.
либо если в обще лень, то через сервисы, которые валидируют бесплатно
на небольших объёмах. но гораздо сложнее определить активность адреса,
есть ли там читатель, или ящик читается раз в месяц, или в обще заброшен.
слать на неактивные почты, с точки зрения отклика - занятие пустое.
 
Не подозрительно ли заваливать серв запросами валидности адресов? Или мои объёмы мизер для хостера типа мелкомягких? Существует ли какой то точный технический метод определения валидности адресов сопоставимый по точности с копанием соцсетей?
Если у тебя корпы, то это скорее всего аутлук.
Вообще есть традиционно три метода определения валидности адреса почты, которыми пользуются в т.ч. сервисы типа https://www.millionverifier.com/, https://tools.emailhippo.com/, https://mailboxlayer.com/
1) по smtp, через команду VRFY. Она отключена у большинства ящиков - https://stackoverflow.com/questions/27474/email-smtp-validator. По-этому...
2) по smtp, через попытку отправить письмо на этот ящик. Так валидируют gmail, например (https://stackoverflow.com/a/11121231/1906976)
Код:
If you can exercise a raw socket then I'd use an approach that I used to do with telnet in the old days.
Do a DNS lookup to find the domain name's MX host.
Open the socket to port 25 to the domain name's MX host.
Send "EHLO yourdomain.com"
Send "MAIL FROM:<you@yourdomain.com>"
Send "RCPT TO:<ashfdhf38hdfhajsfbnbd@gmail.com>"
The response from this will either be success or failure depending upon whether or not the destination mailbox exists on their servers.
Send "QUIT" to abort the session with their SMTP server.
3) Но, есть ящики, которые готовы принять письмо на любой несуществующий адрес, и плюнуть bounce-email в ответ позже. Например yahoo. Такие провайдеры называются "catch-all". Их проверяют через попытку зарегистрировать в них ящик по стандартной процедуре. Писать для каждого такого провайдера ручками скрипты на проверку валидности - штука неблагодарная, но, за нас это уже сделали на гитхабе:
Код проверки валидности ящиков у нужных тебе email-провайдеров проще всего содрать оттуда.

Ну и главный вопрос... а оно тебе надо? если тебя bounce-email-ы не напрягают, то может и бог с ним, т.к. у тебя объемы крошечные, не проще слать в слепую?
Если напрягают только боунсы, то чтобы не убивать смтп, отключить их можно просто добавив этот хедер:
Код:
'Return-Path: <>'
* взято отсюда: https://stackoverflow.com/a/154794/1906976

лав. успехов.
 
Если у тебя корпы, то это скорее всего аутлук.
Вообще есть традиционно три метода определения валидности адреса почты, которыми пользуются в т.ч. сервисы типа https://www.millionverifier.com/, https://tools.emailhippo.com/, https://mailboxlayer.com/
1) по smtp, через команду VRFY. Она отключена у большинства ящиков - https://stackoverflow.com/questions/27474/email-smtp-validator. По-этому...
2) по smtp, через попытку отправить письмо на этот ящик. Так валидируют gmail, например (https://stackoverflow.com/a/11121231/1906976)
Код:
If you can exercise a raw socket then I'd use an approach that I used to do with telnet in the old days.
Do a DNS lookup to find the domain name's MX host.
Open the socket to port 25 to the domain name's MX host.
Send "EHLO yourdomain.com"
Send "MAIL FROM:<you@yourdomain.com>"
Send "RCPT TO:<ashfdhf38hdfhajsfbnbd@gmail.com>"
The response from this will either be success or failure depending upon whether or not the destination mailbox exists on their servers.
Send "QUIT" to abort the session with their SMTP server.
3) Но, есть ящики, которые готовы принять письмо на любой несуществующий адрес, и плюнуть bounce-email в ответ позже. Например yahoo. Такие провайдеры называются "catch-all". Их проверяют через попытку зарегистрировать в них ящик по стандартной процедуре. Писать для каждого такого провайдера ручками скрипты на проверку валидности - штука неблагодарная, но, за нас это уже сделали на гитхабе:
Код проверки валидности ящиков у нужных тебе email-провайдеров проще всего содрать оттуда.

Ну и главный вопрос... а оно тебе надо? если тебя bounce-email-ы не напрягают, то может и бог с ним, т.к. у тебя объемы крошечные, не проще слать в слепую?
Если напрягают только боунсы, то чтобы не убивать смтп, отключить их можно просто добавив этот хедер:
Код:
'Return-Path: <>'
* взято отсюда: https://stackoverflow.com/a/154794/1906976

лав. успехов.

мне чатgpt вот что ответил по поводу Return-Path: <>​

🔸 Что делает Return-Path: <>?​


  • Это пустой Return-Path, он используется только для системных писем — например, для уведомлений о недоставке (bounce messages).
  • Он сигнализирует: «не посылать обратных сообщений», то есть не пересылать недоставки обратно.
  • Также может быть использован в автоматических ответах, чтобы избежать почтовых циклов.



🔸 Можно ли так делать в обычной рассылке?​


❌ Нет. Не рекомендуется.


Добавление Return-Path: <> вручную в обычное письмо:


  • Бесполезно, потому что реальный Return-Path всё равно формируется на SMTP-уровне (через MAIL FROM).
  • Многими серверами игнорируется или перезаписывается.
  • Может вызвать флаги у спам-фильтров, потому что такое поле редко используется в обычной корреспонденции.
  • Некоторые почтовики (особенно корпоративные) могут отвергать письма с Return-Path: <>, если они не являются bounce-уведомлениями.



🔸 Когда допустимо использовать Return-Path: <>?​


✅ Примеры:


  • Почтовый сервер отправляет автоматическое сообщение:
    «Письмо не доставлено. Причина: ящик переполнен».
  • В auto-reply боте, чтобы не попасть в цикл ответов.
 
Если у тебя корпы, то это скорее всего аутлук.
Вообще есть традиционно три метода определения валидности адреса почты, которыми пользуются в т.ч. сервисы типа https://www.millionverifier.com/, https://tools.emailhippo.com/, https://mailboxlayer.com/
1) по smtp, через команду VRFY. Она отключена у большинства ящиков - https://stackoverflow.com/questions/27474/email-smtp-validator. По-этому...
2) по smtp, через попытку отправить письмо на этот ящик. Так валидируют gmail, например (https://stackoverflow.com/a/11121231/1906976)
Код:
If you can exercise a raw socket then I'd use an approach that I used to do with telnet in the old days.
Do a DNS lookup to find the domain name's MX host.
Open the socket to port 25 to the domain name's MX host.
Send "EHLO yourdomain.com"
Send "MAIL FROM:<you@yourdomain.com>"
Send "RCPT TO:<ashfdhf38hdfhajsfbnbd@gmail.com>"
The response from this will either be success or failure depending upon whether or not the destination mailbox exists on their servers.
Send "QUIT" to abort the session with their SMTP server.
3) Но, есть ящики, которые готовы принять письмо на любой несуществующий адрес, и плюнуть bounce-email в ответ позже. Например yahoo. Такие провайдеры называются "catch-all". Их проверяют через попытку зарегистрировать в них ящик по стандартной процедуре. Писать для каждого такого провайдера ручками скрипты на проверку валидности - штука неблагодарная, но, за нас это уже сделали на гитхабе:
Код проверки валидности ящиков у нужных тебе email-провайдеров проще всего содрать оттуда.

Ну и главный вопрос... а оно тебе надо? если тебя bounce-email-ы не напрягают, то может и бог с ним, т.к. у тебя объемы крошечные, не проще слать в слепую?
Если напрягают только боунсы, то чтобы не убивать смтп, отключить их можно просто добавив этот хедер:
Код:
'Return-Path: <>'
* взято отсюда: https://stackoverflow.com/a/154794/1906976

лав. успехов.
Когда то чекали почты: кликер вводил почту в логин, если существует просило пароль, Гугл точно так чекали) сейчас тоже вероятно можно, но заморочей больше
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх