Steuerkram/tests/69_MailFromEmailInjectionTest.php

72 lines
2.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
use Steuerkram\Models\Setting;
use Steuerkram\Services\SmtpMailer;
/**
* Test 69: SMTP-Header-/Kommando-Injection über mail_from_email verhindert (Fix #148).
*/
class MailFromEmailInjectionTest extends TestCase
{
protected string $testName = 'Test 69: mail_from_email – Validierung & SmtpMailer-Härtung';
public function run(): void
{
$before = Setting::get();
$base = array_merge($before, [
'firma' => $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:<angreifer@evil.example>\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:<angreifer@evil.example>");
$this->assert(
!str_contains($result, "\r") && !str_contains($result, "\n"),
'sanitizeAddress() entfernt CR/LF aus der Absenderadresse'
);
}
}