Um filtro de spam que lê todos os idiomas e explica cada decisão.
O Spam Scanner detecta spam, phishing, golpes e malware para Node.js, a linha de comando e servidores de e-mail como Postfix, Exim e Haraka. Cada resultado lista os testes acionados e o motivo.
npm install -g spamscanner
ComeçarAssistir ao vídeo (1:58)
- Node.js 18+
- Milter, spamd, HTTP
- Ollama, Claude, ChatGPT
- Sem telemetria
$ spamscanner scan message.eml SPAM score 16.3 (spam at 5.0, reject at 15.0) action: reject language: en +6.3 BAYES_999 Classifier spam probability 99.9% +5.0 PHISHING_LOOKALIKE_DOMAIN "paypa1-secure.top" imitates paypal by swapping characters +3.0 DECEPTIVE_LINK A link shows "https://www.paypal.com/signin" but goes to paypa1-secure.top +2.0 FROM_NAME_BRAND Display name says "paypal" but the message is from paypa1-secure.top $ echo $? 1
Como uma mensagem é avaliada
Cada verificação adiciona ou remove pontos, e o total decide. Os limites e os pontos podem ser alterados, e nada é uma caixa-preta: o resultado nomeia cada teste.
Ler
A mensagem é analisada e seu texto é normalizado: letras estilizadas, caracteres invisíveis e alfabetos parecidos são desfeitos.
Verificar
As verificações do classificador, de links, anexos, autenticação, listas de bloqueio e regras rodam ao mesmo tempo, cada uma com um tempo limite.
Pontuação
Cada teste adiciona ou remove pontos. Com 5, a mensagem é spam; com 15, o servidor de e-mail deve recusá-la.
Perguntar
Os casos duvidosos podem ir para um modelo de linguagem, que adiciona até 6 pontos ou remove até 3.
- abaixo de 5aceitar
- de 5 a 15marcar como spam
- 15 ou maisrejeitar
O que ele verifica
As palavras são um sinal. Links, remetentes, anexos e autenticação dizem o mesmo tanto, e nenhum deles depende do idioma da mensagem.
Um classificador para todo sistema de escrita
Palavras, pares de palavras, links, remetentes, HTML e anexos, contados e combinados como faz o SpamBayes, com um “incerto” honesto quando as pistas discordam.
Como ele decideTodos os idiomas, com cuidado
Segmentação de palavras do Unicode para chinês, japonês e tailandês, disfarces desfeitos e nenhuma penalidade para um idioma em que o modelo viu pouco ham.
IdiomasPhishing
Domínios parecidos com letras cirílicas ou trocadas, links cujo texto mostra outro endereço, marcas em nomes de exibição e o resolvedor de malware da Cloudflare.
Verificações de phishingAnexos
Executáveis identificados pelos seus bytes, mesmo renomeados para .pdf; extensões duplas; programas em arquivos ZIP; macros do Office; PDFs ativos; ClamAV.
Verificações de anexosAutenticação
SPF, DKIM, DMARC e ARC, listas de bloqueio no DNS, listas de permissão e de bloqueio e uma regra para e-mails que falsificam o seu próprio domínio.
AutenticaçãoModelos de linguagem
Os casos duvidosos vão para um modelo: Ollama na sua própria máquina, ou Claude, ChatGPT, Gemini e qualquer servidor compatível com a OpenAI.
Modelos de linguagem
Todos os idiomas, sem adivinhação
As palavras são encontradas com as regras do Unicode, então idiomas escritos sem espaços funcionam, e os disfarces são desfeitos antes da contagem. Estas são as palavras que o classificador conta, calculadas quando esta página foi gerada.
Um idioma em que o modelo incluído viu pouco ham recebe “incerto” em vez de “spam”, então um e-mail comum em árabe ou coreano nunca é marcado por causa da sua escrita. Idiomas
Claim your fr␣ee prіze: V1agra 𝐅𝐑𝐄𝐄
- claim
- your
- free
- prize
- viagra
- free
Um espaço de largura zero, um і cirílico, um dígito no lugar de uma letra e letras em negrito matemático
恭喜您获得一百万元大奖
- 恭喜
- 您
- 获得
- 一
- 百万
- 元
- 大奖
Segmentado com um dicionário
ยินดีด้วยคุณได้รับรางวัลหนึ่งล้านบาท
- ยินดี
- ด้วย
- คุณ
- ได้
- รับ
- รางวัล
- หนึ่ง
- ล้าน
- บาท
Segmentado com um dicionário
Поздравляем! Вы выиграли миллион
- поздравляем
- вы
- выиграли
- миллион
Em minúsculas pelas regras do Unicode
Conecta-se ao seu servidor de e-mail
Um milter para Postfix e Sendmail, um servidor spamd compatível com o SpamAssassin para spamc, Exim e Haraka, um filtro de conteúdo, uma API HTTP, um servidor TCP e a biblioteca.
Todos adicionam os cabeçalhos X-Spam-Flag, X-Spam-Score, X-Spam-Status e removem os que um remetente tenha forjado.
spamscanner milter --port 7831 --auth --subject-tag "[SPAM]"
# /etc/postfix/main.cf
smtpd_milters = inet:127.0.0.1:7831
milter_default_action = acceptUm milter verifica o e-mail durante a sessão SMTP, então o spam que atinge o limite de rejeição é recusado antes de ser aceito. Guia do Postfix
spamscanner spamd --port 783 --auth
spamc -c < message.eml # prints 16.3/5.0 and exits 1Um servidor spamd compatível com o SpamAssassin: pare o spamd, inicie o Spam Scanner na mesma porta e os clientes do SpamAssassin continuam funcionando. Guia do spamd
import SpamScanner from 'spamscanner';
const scanner = new SpamScanner({authentication: true});
const result = await scanner.scan(stream, {session});
if (result.action === 'reject') {
// refuse with a 4xx or 5xx reply
}A biblioteca, para smtp-server, plugins do Haraka ou qualquer serviço que lide com e-mails. Referência da API
spamscanner http --port 7832 --token "$TOKEN"
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
--data-binary @message.eml "http://127.0.0.1:7832/scan?ip=203.0.113.5"Para qualquer linguagem e qualquer servidor que consiga fazer uma requisição HTTP. Guia da API HTTP
Um modelo de linguagem para os casos duvidosos
Spam evidente e ham evidente nunca chegam a ele. Quando a pontuação fica perto do limite ou o classificador está incerto, um modelo lê a mensagem e responde spam, phishing, golpe, malware ou ham. Execute um na sua própria máquina ou use um hospedado, com qualquer URL, porta e autenticação.
Instruções escondidas em uma mensagem para filtros de IA são pontuadas como spam, e o modelo é avisado de que a mensagem é apenas dado. Os testes de ponta a ponta verificam isso com um modelo real através do Ollama.
- Ollama
- LM Studio
- llama.cpp server
- vLLM
- LocalAI
- Jan
- OpenAI
- Anthropic (Claude)
- Google Gemini
- Mistral AI
- Groq
- OpenRouter
- DeepSeek
- xAI
- Together AI
- Fireworks AI
- Cerebras
- Hugging Face Inference Providers
- Azure OpenAI
- Cloudflare Clef
- Cloudflare Clef Flash
- TypeSafe Jev
- TypeSafe Jev on OpenRouter
- Any decision model server
ollama pull qwen3.5:4b
spamscanner llm-test --llm ollama --llm-model qwen3.5:4b
spamscanner milter --llm ollama --llm-model qwen3.5:4bCom contorno: roda na sua própria máquina. Os dados pessoais são removidos antes de uma mensagem ir para um provedor hospedado.
| Ollama | Licença | Tamanho |
|---|---|---|
qwen3.5:0.8b | Apache-2.0 | 1.3 GB |
gemma4:e2b | Apache-2.0 | 4.6 GB |
qwen3.5:4b | Apache-2.0 | 3.3 GB |
qwen3.5:9b | Apache-2.0 | 6.6 GB |
gpt-oss-safeguard:20b | Apache-2.0 | 14 GB |
Modelos abertos recomendados. Todas as recomendações
Medido e treinável
O modelo incluído é treinado com conjuntos de dados públicos e testado com mensagens que ele não viu. Um modelo treinado com os seus próprios e-mails se sai melhor: treine-o a partir de arquivos mbox, Maildirs ou conjuntos de dados, meça-o e ensine-o com botões de “denunciar spam”.
| Mensagens separadas para teste | Mensagens | Precisão | Revocação | Falsos positivos |
|---|---|---|---|---|
| inglês | 6.564 | 100,0% | 97,1% | 0,0% |
| russo | 1.682 | 100,0% | 97,4% | 0,0% |
| italiano | 1.389 | 98,1% | 85,3% | 1,8% |
| alemão | 1.309 | 97,7% | 76,1% | 2,2% |
| espanhol | 1.281 | 97,5% | 82,6% | 2,6% |
| Todos | 13.840 | 99,2% | 85,1% | 0,6% |
Apenas o classificador, com uma em cada dez mensagens dos seus dados públicos de treinamento, separadas para teste. Mensagens incertas contam como não detectadas. Alemão, italiano e espanhol vêm de conjuntos de dados sintéticos com rótulos imprecisos. Sobre o modelo incluído
Feito para o Forward Email
O Forward Email não guarda registros do conteúdo das mensagens, então não poderia enviar e-mails para um serviço de filtragem externo. O Spam Scanner roda nos seus próprios servidores, não envia nada para lugar nenhum a menos que seja configurado para isso e explica cada decisão sem que uma pessoa leia o e-mail. Forward Email e atualização
Um projeto do Forward Email, o serviço de e-mail focado em privacidade.
