$before['firma'] ?: 'Testfirma', 'strasse' => $before['strasse'] ?: 'Teststr. 1', 'plz' => $before['plz'] ?: '12345', 'ort' => $before['ort'] ?: 'Testort', ]); // Gültige Adresse wird unverändert übernommen Setting::update(array_merge($base, [ 'mail_from_email' => 'rechnung@firma.example', ])); $this->assertEquals('rechnung@firma.example', Setting::get()['mail_from_email'], 'Gültige Absenderadresse wird gespeichert'); // CRLF-Payload (SMTP-Kommando-Injection) wird beim Speichern verworfen, nicht nur bereinigt Setting::update(array_merge($base, [ 'mail_from_email' => "admin@firma.example>\r\nRCPT TO:\r\nDATA", ])); $stored = Setting::get()['mail_from_email']; $this->assert( !str_contains($stored, "\r") && !str_contains($stored, "\n"), 'Gespeicherte Absenderadresse enthält kein CR/LF' ); $this->assertEquals('', $stored, 'Ungültige (CRLF-behaftete) Absenderadresse wird verworfen statt gespeichert'); // Andere ungültige Werte (kein E-Mail-Format) werden ebenfalls verworfen Setting::update(array_merge($base, [ 'mail_from_email' => 'keine-email-adresse', ])); $this->assertEquals('', Setting::get()['mail_from_email'], 'Nicht-E-Mail-Wert wird verworfen'); // Ursprünglichen Zustand wiederherstellen Setting::update(array_merge($base, [ 'mail_from_email' => $before['mail_from_email'] ?? '', ])); // Defense-in-depth: SmtpMailer::sanitizeAddress() entfernt CRLF selbst, // falls eine mit CRLF behaftete Adresse trotzdem in den Mailer gelangt. $mailer = new SmtpMailer( host: '127.0.0.1', port: 1, encryption: 'none', user: '', pass: '', fromEmail: 'absender@example.com', fromName: 'Absender', ); $ref = new \ReflectionMethod($mailer, 'sanitizeAddress'); $ref->setAccessible(true); $result = $ref->invoke($mailer, "admin@firma.example>\r\nRCPT TO:"); $this->assert( !str_contains($result, "\r") && !str_contains($result, "\n"), 'sanitizeAddress() entfernt CR/LF aus der Absenderadresse' ); } }