API-Referenz

JavaScript
import SpamScanner from 'spamscanner';             // ESM
const SpamScanner = require('spamscanner');        // CommonJS

const scanner = new SpamScanner(options);
const result = await scanner.scan(rawMessage, scanOptions);

Erstellen Sie einen Scanner und verwenden Sie ihn wieder: Er lädt das Modell einmal und speichert Antworten von DNS und Sprachmodell zwischen.

Optionen#

Jede Option kann an den Konstruktor übergeben werden. Die meisten lassen sich auch für eine einzelne Nachricht an scan() übergeben und überschreiben dann die des Konstruktors.

OptionStandardBedeutung
threshold5Score, ab dem eine Nachricht Spam ist
rejectThreshold15Score, ab dem action den Wert reject hat
scores{}Punkte pro Test: Einstellungsschlüssel oder Testnamen (Tests und Scores)
classifiermitgeliefertes ModellEin Classifier, ein Modellobjekt, ein Pfad zu einer Modelldatei oder false
classifierOptions{}Optionen für das mitgelieferte Modell (siehe Classifier)
allowedLanguages[]ISO-639-1-Codes; andere Sprachen erhalten LANGUAGE_NOT_ALLOWED
phishing.cloudflaretrueDie filternden Resolver von Cloudflare zu Link-Hosts befragen
phishing.adulttrueZusätzlich den Familien-Resolver befragen, der Seiten für Erwachsene blockiert
phishing.maxHosts25Pro Nachricht abgefragte Link-Hosts
phishing.homograph{}brands (ersetzt die eingebaute Liste), extraBrands, allowlist (nie markierte Domains), strictMode
dnsbl{ip: [], domain: []}Zonen von DNS-Blocklisten für die Client-IP und für Link-Domains
dns{servers: null, timeout: 3000}Nameserver für DNS-Prüfungen (Standard: die des Systems)
attachmentstrueAnhänge untersuchen
macrostrueMakros, aktive PDFs und RTF-Objekte markieren
arbitrarytrueDie Regeln ausführen
authenticationfalsetrue oder {dnsServers, timeout, mta, weights}: SPF, DKIM, DMARC, ARC
reputationfalse{allowlist, denylist, apiUrl, headers, timeout}
allowlist, denylistIP-Adressen, Domains oder Adressen; Kurzform für reputation
clamavfalsetrue (Standard-Socket), {socket} oder {host, port}
llmnullEinstellungen für das Sprachmodell, mit mode, minScore, maxScore
toxicityfalse{model, threshold = 0.7}: ein Modell, dessen classify([text]) wie @tensorflow-models/toxicity antwortet
nsfwfalse{model, threshold = 0.6}: ein Modell, dessen classify(imageBuffer) wie nsfwjs antwortet
maxLength100000Gelesene Zeichen des Nachrichtentexts
timeout10000Erlaubte Millisekunden pro Netzwerkprüfung
session{}Standardangaben zur SMTP-Sitzung

scan() nimmt außerdem session entgegen:

JavaScript
await scanner.scan(raw, {
  session: {
    remoteAddress: '203.0.113.5',             // the client's IP address
    resolvedClientHostname: 'mx.example.com', // its verified reverse DNS name
    helo: 'mx.example.com',
    envelope: {
      mailFrom: {address: 'alice@example.com'},
      rcptTo: [{address: 'bob@example.org'}],
    },
  },
});

Ein Server, der SPFSender Policy Framework: ein DNS-Eintrag, der die Server auflistet, die für eine Domain E-Mails senden dürfen., DKIMDomainKeys Identified Mail: eine Signatur über eine Nachricht, geprüft mit einem öffentlichen Schlüssel aus dem DNS des Absenders., DMARCEine DNS-Richtlinie, die Empfängern sagt, was mit E-Mails geschehen soll, die sich auf eine Domain berufen, aber die SPF- und DKIM-Ausrichtung nicht bestehen. und ARCAuthenticated Received Chain: Signaturen, die Authentifizierungsergebnisse über weiterleitende Server hinweg mitführen. bereits geprüft hat (mit mailauth), kann seine Ergebnisse als authenticationResults übergeben, und sie werden bewertet statt erneut geprüft:

JavaScript
import {authenticate} from 'mailauth';

const auth = await authenticate(raw, {ip, helo, sender, mta});
await scanner.scan(raw, {authenticationResults: auth});

Methoden#

MethodeRückgabe
scan(source, options)Das Ergebnis. source ist ein Buffer, String, Uint8Array oder lesbarer Stream
scanFile(path, options)Das Ergebnis für eine Nachrichtendatei
learn(source, 'spam' | 'ham')Bringt dem Klassifikator eine Nachricht bei
unlearn(source, 'spam' | 'ham')Macht learn rückgängig
saveModel(path, options)Schreibt den Klassifikator in eine Datei (options: minCount, maxFeatures, metadata)
getClassifier()Der verwendete Classifier oder null
getClassification(features)Das Urteil des Klassifikators für Merkmale aus getFeatures
getFeatures(mail){features, words, language, script, links, hosts, text, hidden} einer Nachricht
getTokens(text, locale)Die Wörter eines Texts
getTokensAndMailFromSource(source){tokens, features, mail}
parse(source){raw, mail}, mit mail aus mailparser

In getFeatures ist text der Text, den ein Mailprogramm anzeigt und aus dem die Wörter gelesen werden, und hidden die Anzahl der Textzeichen, die das HTML versteckt.

scanner.metrics enthält totalScans, averageTime und lastScanTime.

Das Ergebnis#

JavaScript
{
  isSpam: true,
  score: 16.25,
  threshold: 5,
  rejectThreshold: 15,
  action: 'reject',                       // 'accept', 'tag' or 'reject'
  message: 'Spam (BAYES_999, PHISHING_LOOKALIKE_DOMAIN, DECEPTIVE_LINK, FROM_NAME_BRAND)',
  tests: [
    {name: 'BAYES_999', score: 6.25, description: 'Classifier spam probability 99.9%'},
    {name: 'PHISHING_LOOKALIKE_DOMAIN', score: 5, description: '"paypa1-secure.top" imitates paypal by swapping characters'},
    // ...
  ],
  results: {
    classification: {probability, category, spam, ham, clues, coverage},
    phishing: [],        // lookalike domains, deceptive links, Cloudflare and URIBL findings
    uncheckedHosts: 0,   // link hosts beyond phishing.maxHosts, not looked up
    attachments: [],     // every attachment finding
    executables: [],     // the executable findings among them
    macros: [],          // macros, active PDFs, RTF objects
    viruses: [],         // ClamAV findings: {filename, virus: [names], message}
    arbitrary: [],       // rules strong enough to mark spam alone
    obfuscation: {invisible, mixed, styled},
    authentication: null, // mailauth's results with a score, when checked
    reputation: null,
    dnsbl: [],           // {zone, value} for each listing
    language: {language, script, notAllowed},
    llm: null,           // the language model's verdict, when asked
    toxicity: [],
    nsfw: [],
    idnHomographAttack: {detected, domains, riskScore},
  },
  links: ['http://paypa1-secure.top/login'],
  language: 'en',
  tokens: ['dear', 'customer', /* ... */],
  mail: {/* the parsed message, from mailparser */},
  version: '7.0.0',
  metrics: {totalTime: 42},
}

Befunde in phishing, attachments, executables, macros, viruses und arbitrary sind Objekte mit einem type und einer message. String(finding) ergibt die Meldung.

Exporte#

JavaScript
import SpamScanner, {
  Classifier, getFeatures, segmentWords, detectLanguage,
  LLMClassifier, PROVIDERS, RECOMMENDED_MODELS, CLASSIFIER_MODELS,
  DEFAULT_SCORES, scoreResults, spamHeaders, rewriteMessage,
  loadModel, saveModel, defaultModelPath, loadDefaultModel,
  train, evaluate, readExamples,
  MilterServer, createHttpServer, createTcpServer, createSpamdServer,
  DEFAULTS, VERSION,
} from 'spamscanner';

import ArfParser from 'spamscanner/arf';

Classifier#

JavaScript
const classifier = new Classifier({spamCutoff: 0.99, hamCutoff: 0.2});
classifier.learn(getFeatures(mail).features, 'spam');
classifier.classify(features); // {probability, category, spam, ham, clues, coverage}
OptionStandardBedeutung
strength, unknown0.45, 0.5Robinsons s und x: wie stark seltene Merkmale in Richtung 0,5 gezogen werden
minDistance0.1Merkmale, die näher als dieser Wert an 0,5 liegen, werden ignoriert
maxClues150Pro Nachricht kombinierte stärkste Merkmale
hamCutoff, spamCutoff0.2, 0.99Grenzen des Bereichs unsure
minLanguageExamples, languageShare1000, 0.02Nachrichten jeder Klasse, die eine Sprache für volle Konfidenz braucht
languagePriortrueWörter an den Zählungen ihrer eigenen Sprache gewichten

Außerdem stehen merge(other), toJSON(options), Classifier.fromJSON(json), size und entries() zur Verfügung.

Training#

JavaScript
import {train, evaluate, saveModel} from 'spamscanner';

const {classifier, spam, ham} = await train({
  spam: ['/mail/Junk'],
  ham: ['/mail/Archive', '/mail/archive.mbox'],
  datasets: [{file: 'extra.csv', textColumn: 'body', labelColumn: 'kind'}],
});
saveModel(classifier, 'model.json');

evaluate(classifier, examples) nimmt {label, features}-Einträge entgegen oder readExamples(sources), das dieselben Quellen liest wie train, und gibt Zählungen, Präzision, Trefferquote, F1, Genauigkeit sowie die Raten für Fehlalarme, übersehenen Spam und unsichere Fälle zurück.

Server#

JavaScript
import SpamScanner, {MilterServer, createHttpServer, createSpamdServer} from 'spamscanner';

const scanner = new SpamScanner({authentication: true});
const milter = new MilterServer(scanner, {reject: true, rejectCode: 451, subjectTag: '[SPAM]'});
milter.on('scan', ({session, result}) => console.log(session.remoteAddress, result.score));
await milter.listen(7831);

createHttpServer(scanner, {token: process.env.SPAMSCANNER_TOKEN}).listen(7832, '127.0.0.1');
createSpamdServer(scanner).listen(783, '127.0.0.1');

ARF-Berichte#

spamscanner/arf liest und schreibt Abuse-Feedback-Berichte (RFC 5965), das Format, mit dem Postfachanbieter Spam-Beschwerden melden:

JavaScript
import ArfParser from 'spamscanner/arf';

const report = await ArfParser.parse(rawReport);
console.log(report.feedbackType, report.sourceIp, report.originalHeaders.subject);

const raw = ArfParser.create({
  feedbackType: 'abuse', userAgent: 'MyService/1.0',
  from: 'abuse@example.com', to: 'fbl@example.net',
  originalMessage, sourceIp: '192.0.2.1',
});

ArfParser.tryParse() gibt bei Nachrichten, die keine Berichte sind, null zurück, statt einen Fehler zu werfen, und isArfMessage(mail) prüft eine geparste Nachricht.

Diese Seite auf GitHub bearbeiten · Markdown ·