74 lines
2.9 KiB
PHP
74 lines
2.9 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use Steuerkram\Services\SmtpMailer;
|
||
|
||
class EmailHeaderInjectionTest extends TestCase
|
||
{
|
||
protected string $testName = 'Test 50: E-Mail-Header-Injection über Empfänger-/CC-Adressen verhindert';
|
||
|
||
public function run(): void
|
||
{
|
||
$mailer = new SmtpMailer(
|
||
host: '127.0.0.1',
|
||
port: 1, // reservierter Port, Verbindung wird sofort abgelehnt
|
||
encryption: 'none',
|
||
user: '',
|
||
pass: '',
|
||
fromEmail: 'absender@example.com',
|
||
fromName: 'Absender',
|
||
);
|
||
|
||
// CRLF-Injection im Empfänger wird abgelehnt, bevor eine Verbindung aufgebaut wird
|
||
try {
|
||
$mailer->send(
|
||
["opfer@example.com\r\nRCPT TO:<angreifer@example.com>"],
|
||
'Betreff',
|
||
'Text',
|
||
);
|
||
$this->assert(false, 'CRLF-Adresse wirft RuntimeException');
|
||
} catch (\RuntimeException $e) {
|
||
$this->assert(true, 'CRLF-Adresse wirft RuntimeException');
|
||
}
|
||
|
||
// Zusätzlicher Header via Newline im To-Feld wird abgelehnt
|
||
try {
|
||
$mailer->send(
|
||
["opfer@example.com\nBcc: angreifer@example.com"],
|
||
'Betreff',
|
||
'Text',
|
||
);
|
||
$this->assert(false, 'Header-Injection-Adresse wirft RuntimeException');
|
||
} catch (\RuntimeException $e) {
|
||
$this->assert(true, 'Header-Injection-Adresse wirft RuntimeException');
|
||
}
|
||
|
||
// Grob fehlerhaftes Format wird abgelehnt
|
||
try {
|
||
$mailer->send(['keine-email-adresse'], 'Betreff', 'Text');
|
||
$this->assert(false, 'Ungültiges Format wirft RuntimeException');
|
||
} catch (\RuntimeException $e) {
|
||
$this->assert(true, 'Ungültiges Format wirft RuntimeException');
|
||
}
|
||
|
||
// Kunde: CC-Adressen mit CRLF/ungültigem Format werden vom Model nicht blind übernommen,
|
||
// sondern müssen weiterhin filter_var-tauglich sein, bevor sie je in den Mailer gelangen
|
||
$this->assert(
|
||
filter_var("opfer@example.com\r\nRCPT TO:<x@x.com>", FILTER_VALIDATE_EMAIL) === false,
|
||
'filter_var erkennt CRLF-Payload als ungültig'
|
||
);
|
||
|
||
// Regressionsschutz: gültige Adressen funktionieren weiterhin (Verbindungsaufbau schlägt
|
||
// erwartungsgemäß fehl, da kein echter SMTP-Server erreichbar ist – Validierung selbst greift nicht)
|
||
try {
|
||
$mailer->send(['gueltig@example.com'], 'Betreff', 'Text');
|
||
$this->assert(false, 'Verbindung zu Dummy-Host sollte fehlschlagen');
|
||
} catch (\RuntimeException $e) {
|
||
$this->assert(
|
||
str_contains($e->getMessage(), 'SMTP-Verbindung') || !str_contains($e->getMessage(), 'Ungültige E-Mail-Adresse'),
|
||
'Gültige Adresse wird nicht durch Validierung blockiert (Fehler: ' . $e->getMessage() . ')'
|
||
);
|
||
}
|
||
}
|
||
}
|