89 lines
4.0 KiB
PHP
89 lines
4.0 KiB
PHP
<?php
|
|
/**
|
|
* blitzbestaetigung_process.php
|
|
* Erkennt Bots, die einen Bestaetigungslink ungewoehnlich schnell nach der
|
|
* Anmeldung anklicken (z. B. automatisiertes Adress-Scanning bei fremden
|
|
* Organisationen). Kriterium: kurze Zeitspanne UND abweichende IP zwischen
|
|
* Anmeldung und Bestaetigung (siehe Wiki-Kapitel 7.2 fuer die Begruendung,
|
|
* warum reine Zeitspanne allein NICHT ausreicht).
|
|
*
|
|
* Verhalten bei Treffer:
|
|
* - Abonnent wird auf "unbestaetigt" zurueckgesetzt
|
|
* - IP wird zur Sperrliste vorgemerkt (Attribut "IP sperren")
|
|
* - NUR die IP wird an Stop Forum Spam gemeldet, NICHT die E-Mail-Adresse
|
|
* (koennte einem unbeteiligten Dritten gehoeren, siehe Wiki-Kapitel 7.4)
|
|
*
|
|
* Voraussetzungen:
|
|
* - phpList-Attribut "IP sperren" (Checkbox, siehe blocklist_update.php)
|
|
* - phpList-Attribut "Blitzbestaetigung - eher Bots" (Checkbox, Duplikatschutz)
|
|
*
|
|
* WICHTIG: Vor produktivem Einsatz zunaechst nur mit SELECT testen
|
|
* (siehe Wiki-Kapitel 7.5)!
|
|
*
|
|
* Aufruf: per Cron, z. B. stuendlich
|
|
*/
|
|
|
|
$dbHost = '127.0.0.1';
|
|
$dbName = 'DEINE_DB';
|
|
$dbUser = 'DEIN_DB_USER';
|
|
$dbPass = 'DEIN_DB_PASSWORT';
|
|
$sfsApiKey = 'DEIN_STOPFORUMSPAM_API_KEY';
|
|
|
|
$pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass);
|
|
|
|
$attrIpBlockId = X; // ID des "IP sperren"-Attributs
|
|
$attrBlitzId = Y; // ID des "Blitzbestaetigung"-Attributs
|
|
$thresholdSeconds = 120; // < 2 Minuten zwischen Anmeldung und Bestaetigung = verdaechtig
|
|
|
|
$sql = "SELECT u.id, u.email,
|
|
sub.ip AS sub_ip, conf.ip AS conf_ip,
|
|
TIMESTAMPDIFF(SECOND, sub.date, conf.date) AS diff_seconds
|
|
FROM phplist_user_user u
|
|
JOIN phplist_user_user_history sub ON sub.userid = u.id AND sub.summary IN ('Subscription','Re-Subscription')
|
|
JOIN phplist_user_user_history conf ON conf.userid = u.id AND conf.summary = 'Confirmation'
|
|
LEFT JOIN phplist_user_user_attribute uab ON uab.userid = u.id AND uab.attributeid = :blitzId
|
|
WHERE u.confirmed = 1
|
|
AND TIMESTAMPDIFF(SECOND, sub.date, conf.date) BETWEEN 0 AND :threshold
|
|
AND sub.ip != conf.ip
|
|
AND (uab.value IS NULL OR uab.value = '')
|
|
GROUP BY u.id";
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute(['blitzId' => $attrBlitzId, 'threshold' => $thresholdSeconds]);
|
|
$candidates = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
foreach ($candidates as $c) {
|
|
// 1. Abonnent auf "unbestaetigt" zuruecksetzen
|
|
$reset = $pdo->prepare("UPDATE phplist_user_user SET confirmed = 0 WHERE id = :uid");
|
|
$reset->execute(['uid' => $c['id']]);
|
|
|
|
// 2. IP zur Sperrliste vormerken (nutzt bestehende Infrastruktur aus blocklist_update.php)
|
|
$blk = $pdo->prepare("INSERT INTO phplist_user_user_attribute (userid, attributeid, value)
|
|
VALUES (:uid, :aid, 'on')
|
|
ON DUPLICATE KEY UPDATE value = 'on'");
|
|
$blk->execute(['uid' => $c['id'], 'aid' => $attrIpBlockId]);
|
|
|
|
// 3. Nur die IP an SFS melden - NICHT die moeglicherweise fremde E-Mail-Adresse
|
|
$data = http_build_query([
|
|
'ip_addr' => $c['conf_ip'],
|
|
'username' => 'blitzbestaetigung-bot',
|
|
'api_key' => $sfsApiKey,
|
|
'evidence' => "Automatisiert erkannt: Bestaetigung nach nur {$c['diff_seconds']}s von abweichender IP (Anmelde-IP: {$c['sub_ip']})",
|
|
]);
|
|
$ch = curl_init('https://www.stopforumspam.com/add.php');
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_exec($ch);
|
|
curl_close($ch);
|
|
|
|
// 4. Als bearbeitet markieren (Duplikatschutz)
|
|
$mark = $pdo->prepare("INSERT INTO phplist_user_user_attribute (userid, attributeid, value)
|
|
VALUES (:uid, :aid, 'on')
|
|
ON DUPLICATE KEY UPDATE value = 'on'");
|
|
$mark->execute(['uid' => $c['id'], 'aid' => $attrBlitzId]);
|
|
|
|
echo "Zurueckgesetzt & IP vorgemerkt: userid {$c['id']} ({$c['diff_seconds']}s, sub_ip: {$c['sub_ip']}, conf_ip: {$c['conf_ip']})\n";
|
|
sleep(1);
|
|
}
|