From d666fb635964c5e403dee78b465dffdae08d59dd Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Tue, 3 Feb 2026 10:33:36 -0500 Subject: [PATCH] Escape ID parameters to prevent injection --- src/Connection/ImapConnection.php | 2 +- tests/Unit/Connection/ImapConnectionTest.php | 22 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Connection/ImapConnection.php b/src/Connection/ImapConnection.php index 5e1cc75..b9b72f6 100644 --- a/src/Connection/ImapConnection.php +++ b/src/Connection/ImapConnection.php @@ -539,7 +539,7 @@ public function id(?array $ids = null): UntaggedResponse $token = '('; foreach ($ids as $id) { - $token .= '"'.$id.'" '; + $token .= '"'.Str::escape($id).'" '; } $token = rtrim($token).')'; diff --git a/tests/Unit/Connection/ImapConnectionTest.php b/tests/Unit/Connection/ImapConnectionTest.php index c486e51..1cbc2fc 100644 --- a/tests/Unit/Connection/ImapConnectionTest.php +++ b/tests/Unit/Connection/ImapConnectionTest.php @@ -648,6 +648,28 @@ expect($response->type()->is('ID'))->toBeTrue(); }); +test('id escapes special characters to prevent command injection', function () { + $stream = new FakeStream; + $stream->open(); + + $stream->feed([ + '* OK Welcome to IMAP', + '* ID NIL', + 'TAG1 OK ID completed', + ]); + + $connection = new ImapConnection($stream); + $connection->connect('imap.example.com'); + + $connection->id([ + 'name' => 'Evil"Client', + 'version' => "1.0\r\nLOGOUT", + 'vendor' => 'Test\\Vendor', + ]); + + $stream->assertWritten('TAG1 ID ("Evil\\"Client" "1.0LOGOUT" "Test\\\\Vendor")'); +}); + test('expunge', function () { $stream = new FakeStream; $stream->open();