Pentest 83.1-83.3: Auto-Import-Pfad härten
83.1 MEDIUM: Auto-Import in syncForwardingForEmail rief assertValidForwardingEmail nicht auf. Plesk-Member wie attacker@plesk.internal wären ohne TLD-Block-Check (71.1) in die DB importiert worden. Fix: jeder importierte Member läuft durch assertValidForwardingEmail, ungültige werden silent gedroppt + auf debug-Level geloggt. 83.2 LOW: Self-Forward-Schutz (81.1) griff nur im Add-Pfad. Wenn Plesk die eigene Adresse als Mailgroup-Member führte, wäre sie beim Auto-Import in die DB-Liste gerutscht → nach dem Umschalten auf Forwarding Mail-Loop. Fix: seenKeys mit der eigenen Adresse initialisieren bevor die Import-Schleife läuft. 83.3 INFO: PII-Log auf console.debug umgestellt (statt console.log). Smoke-Test mit gemischter Plesk-Liste: legitimer Member importiert, reservierte TLDs + Self-Mail (exakt + Plus-Tag) abgelehnt, Customer-Stamm + Default deduped.
This commit is contained in:
@@ -566,6 +566,12 @@ export async function syncForwardingForEmail(
|
||||
// additionalForwardingEmails-Liste rein. Der nachfolgende Plesk-Call
|
||||
// deaktiviert dann die Mailgroup und schreibt die volle Liste als
|
||||
// Forwarding. Verlustfrei – kein Empfänger fällt raus.
|
||||
// Pentest 83.2: Self-Forward auch beim Import blocken. Die
|
||||
// Stressfrei-Adresse selbst darf nicht aus Plesk in unsere DB
|
||||
// landen – sonst läuft sie nach dem Mailgroup→Forwarding-Umschalten
|
||||
// als Forwarding-Target auf sich selbst (Mail-Loop).
|
||||
seenKeys.add(canonicalEmailKey(stressfreiEmail.email));
|
||||
|
||||
try {
|
||||
const pleskState = await checkEmailExists(localPart);
|
||||
const existingMembers = [
|
||||
@@ -574,11 +580,26 @@ export async function syncForwardingForEmail(
|
||||
];
|
||||
const newImports: string[] = [];
|
||||
for (const member of existingMembers) {
|
||||
const key = canonicalEmailKey(member);
|
||||
// Pentest 83.1: importierte Adressen aus Plesk müssen denselben
|
||||
// Filter passieren wie User-Eingaben (TLD-Blocklist, Format).
|
||||
// Sonst rutschen reservierte TLDs wie `.internal` ohne Check
|
||||
// in unsere DB, falls ein Plesk-Admin sie dort manuell gepflegt
|
||||
// hat. Ungültige werden silent gedroppt – Log informiert.
|
||||
let validated: string;
|
||||
try {
|
||||
validated = assertValidForwardingEmail(member);
|
||||
} catch (validationErr) {
|
||||
const reason = validationErr instanceof Error ? validationErr.message : 'unbekannt';
|
||||
console.debug(
|
||||
`[syncForwardingForEmail] Plesk-Member "${member}" verworfen: ${reason}`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
const key = canonicalEmailKey(validated);
|
||||
if (!seenKeys.has(key)) {
|
||||
seenKeys.add(key);
|
||||
forwardTargets.push(member);
|
||||
newImports.push(member);
|
||||
forwardTargets.push(validated);
|
||||
newImports.push(validated);
|
||||
}
|
||||
}
|
||||
if (newImports.length > 0) {
|
||||
@@ -590,7 +611,8 @@ export async function syncForwardingForEmail(
|
||||
where: { id },
|
||||
data: { additionalForwardingEmails: serializeAdditionalForwards(mergedAdditional) },
|
||||
});
|
||||
console.log(
|
||||
// Pentest 83.3: PII-Logs auf debug-Level statt log-Level.
|
||||
console.debug(
|
||||
`[syncForwardingForEmail] Importiert aus Plesk-Mailgroup für ${stressfreiEmail.email}:`,
|
||||
newImports,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user