Pentest 81.1 (MEDIUM): Self-Forward erzeugte Mail-Loop am Provider
Bug: Die Stressfrei-Adresse selbst (max@stressfrei-wechseln.net) konnte als zusätzliches Weiterleitungsziel eingetragen werden, auch Plus-Varianten. Plesk leitet auf sich selbst um → Mail-Loop. Backend setAdditionalForwards: lädt zusätzlich meta.email, vergleicht canonicalEmailKey gegen canonicalEmailKey(meta.email). Bei Treffer hartes ApiError(400) mit klarer "zeigt auf die Adresse selbst – Mail-Loop"-Meldung statt silent dedup – der User soll merken, dass sein Eintrag bewusst abgelehnt wurde. Frontend AdditionalForwardsModal: zusätzliche proaktive Validierung im Sub-Modal mit identischem canonicalize-Helper. Neuer selfEmail- Prop, damit auch der Create-Modus (vor Persist) den Check fahren kann. Spart Roundtrip + sofort sprechende Meldung.
This commit is contained in:
@@ -292,15 +292,21 @@ export async function deleteEmail(id: number) {
|
||||
*
|
||||
* Pentest 71.4: DB-Update wird bei Provider-Sync-Fehler zurückgerollt,
|
||||
* damit Plesk und DB nicht auseinanderlaufen.
|
||||
*
|
||||
* Pentest 81.1: Self-Forward wird hart abgelehnt – würde sonst am
|
||||
* Provider einen Mail-Loop erzeugen (Stressfrei-Adresse leitet auf
|
||||
* sich selbst um → unendliche Weiterleitung).
|
||||
*/
|
||||
export async function setAdditionalForwards(
|
||||
id: number,
|
||||
emails: string[],
|
||||
): Promise<{ success: boolean; forwardTargets?: string[]; error?: string }> {
|
||||
// Kunden-Stamm-Mail holen für Dedup gegen das (immer mit-gesetzte) Default-Ziel.
|
||||
// Kunden-Stamm-Mail + eigene Email holen für Dedup gegen die fest
|
||||
// gesetzten Ziele bzw. die Stressfrei-Adresse selbst.
|
||||
const meta = await prisma.stressfreiEmail.findUnique({
|
||||
where: { id },
|
||||
select: {
|
||||
email: true,
|
||||
additionalForwardingEmails: true,
|
||||
customer: { select: { email: true } },
|
||||
},
|
||||
@@ -312,6 +318,7 @@ export async function setAdditionalForwards(
|
||||
const customerEmailKey = meta.customer?.email
|
||||
? canonicalEmailKey(meta.customer.email)
|
||||
: null;
|
||||
const selfKey = canonicalEmailKey(meta.email);
|
||||
|
||||
// Input normalisieren + Duplikate raus.
|
||||
const seen = new Set<string>();
|
||||
@@ -320,6 +327,16 @@ export async function setAdditionalForwards(
|
||||
for (const raw of emails) {
|
||||
const ok = assertValidForwardingEmail(raw);
|
||||
const key = canonicalEmailKey(ok);
|
||||
// 81.1: Eintrag, der auf die Adresse selbst zeigt, würde einen
|
||||
// Mail-Loop am Provider erzeugen. Hart ablehnen mit klarer
|
||||
// Fehlermeldung, statt silent zu droppen – der User soll merken,
|
||||
// dass sein Eintrag bewusst nicht akzeptiert wurde.
|
||||
if (key === selfKey) {
|
||||
throw new ApiError(
|
||||
400,
|
||||
`"${ok}" zeigt auf die Adresse selbst – Mail-Loop. Bitte eine andere Weiterleitungsadresse wählen.`,
|
||||
);
|
||||
}
|
||||
if (!seen.has(key)) {
|
||||
seen.add(key);
|
||||
cleaned.push(ok);
|
||||
|
||||
Reference in New Issue
Block a user