Central de Ajuda

Guia da Central de Ajuda

Como enviar e-mail de formulário com segurança usando SMTP e PHP

Um formulário de contato não deve confiar apenas na função mail() nem colocar o endereço digitado pelo visitante no cabeçalho From. A abordagem mais confiável usa uma biblioteca mantida, SMTP autenticado, validação dos campos, proteção contra automação e registros DNS de entregabilidade.

Arquitetura recomendada

  1. O navegador envia os dados por HTTPS para seu backend.
  2. O backend valida tamanho, formato e conteúdo.
  3. Uma proteção contra spam limita abuso.
  4. A aplicação autentica em uma conta SMTP do seu domínio.
  5. O campo From usa essa conta; o e-mail do visitante vai em Reply-To.
  6. Erros são registrados sem salvar senha nem conteúdo sensível desnecessário.

Prepare a conta de envio

No cPanel, crie uma conta específica, como site@seudominio.com.br. Em Email Accounts > Connect Devices, copie servidor SMTP, porta e criptografia. Use uma senha exclusiva e guarde-a em variável de ambiente ou cofre de segredos, fora do repositório.

Instale o PHPMailer

composer require phpmailer/phpmailer

O Composer deve ser executado no ambiente de desenvolvimento ou no fluxo de implantação. Não exponha o diretório vendor para download e mantenha dependências atualizadas.

Exemplo seguro de envio

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require __DIR__ . '/vendor/autoload.php';

$name = trim((string) ($_POST['name'] ?? ''));
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
$message = trim((string) ($_POST['message'] ?? ''));

if ($name === '' || !$email || $message === '' ||
    mb_strlen($name) > 120 || mb_strlen($message) > 5000) {
    http_response_code(422);
    exit('Revise os campos informados.');
}

$mail = new PHPMailer(true);

try {
    $mail->isSMTP();
    $mail->Host = getenv('SMTP_HOST');
    $mail->SMTPAuth = true;
    $mail->Username = getenv('SMTP_USER');
    $mail->Password = getenv('SMTP_PASS');
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
    $mail->Port = 465;
    $mail->CharSet = 'UTF-8';

    $mail->setFrom(getenv('SMTP_USER'), 'Site da empresa');
    $mail->addAddress('atendimento@seudominio.com.br');
    $mail->addReplyTo($email, $name);
    $mail->Subject = 'Novo contato pelo site';
    $mail->Body = "Nome: {$name}\nE-mail: {$email}\n\n{$message}";

    $mail->send();
    echo 'Mensagem enviada.';
} catch (Exception $exception) {
    error_log('Falha no formulário: ' . $mail->ErrorInfo);
    http_response_code(500);
    echo 'Não foi possível enviar agora. Tente novamente.';
}
Ajuste à sua conta: a porta 465 com SMTPS é um exemplo comum. Use exatamente porta, criptografia e hostname mostrados no cPanel. Para porta 587, a configuração normalmente usa STARTTLS.

Proteja o formulário contra abuso

  • token CSRF para requisições da própria sessão;
  • campo “honeypot” invisível para bots simples;
  • limite de requisições por IP e por sessão;
  • CAPTCHA quando o risco justificar;
  • limites de tamanho e lista explícita de campos;
  • escape ao exibir qualquer conteúdo enviado;
  • bloqueio de anexos ou validação rigorosa de tipo, conteúdo e tamanho;
  • logs com retenção e proteção adequadas à privacidade.

SPF, DKIM e DMARC

Em Email Deliverability, verifique SPF e DKIM. O DMARC deve ser publicado de forma gradual e monitorada. Esses registros não corrigem um formulário vulnerável, mas ajudam servidores destinatários a validar o domínio. Se o DNS estiver na Cloudflare ou em outro provedor, publique os registros no DNS autoritativo, não apenas no cPanel.

Por que não usar o visitante como From

Se alguém informa pessoa@gmail.com e o seu servidor envia como se fosse o Gmail, SPF e DMARC podem falhar. Use uma conta do seu domínio no From e o endereço validado do visitante em Reply-To. Também remova quebras de linha e limite campos para evitar injeção de cabeçalhos.

Diagnóstico

  • Authentication failed: revise usuário completo, senha e autenticação SMTP.
  • Connection timed out: revise host, porta, firewall e se o provedor permite saída nessa porta.
  • TLS/certificate error: use o hostname seguro indicado pelo serviço; não desative validação do certificado.
  • Envia, mas cai no spam: confira conteúdo, reputação, SPF, DKIM, DMARC e se o destinatário marcou mensagens anteriores.
  • Limite excedido: não use hospedagem comum para disparos em massa; adote um serviço transacional apropriado.

Checklist antes de publicar

  • HTTPS ativo;
  • senha fora do código e do Git;
  • From pertencente ao domínio autenticado;
  • Reply-To validado;
  • CSRF, rate limit e antispam ativos;
  • mensagem de erro não revela detalhes internos;
  • teste em Gmail, Outlook e outro domínio;
  • política de privacidade informa o tratamento dos dados.

Novos guias relacionados

Aprofunde o diagnóstico com estes conteúdos atualizados:

Recursos relacionados

Continue com materiais e serviços relacionados ao tema deste guia.

Este guia resolveu sua dúvida? Seu retorno ajuda a priorizar as próximas revisões.
Atendimento técnico

Não encontrou o resultado esperado?

Abra um chamado e envie a mensagem de erro completa, o domínio ou serviço afetado, o horário do teste e capturas de tela sem senhas.