expose icon indicating copy to clipboard operation
expose copied to clipboard

[Bug]: Crash on malformed/empty Cookie header in proxied requests (Cookie:) - Laminas Cookie.php:78

Open creaminds opened this issue 4 months ago • 1 comments

System architecture

Mac, ARM64 (M1, M2, etc)

PHP Version

php 8.3 - binary run over Laravel Herd

Bug description

When Expose is used to tunnel a Laravel application (using Herd), if a POST request to the public URL includes an explicit but empty Cookie header (Cookie:), Expose crashes and logs a Malformed Cookie header found RuntimeException from Laminas\Http\Header\Cookie::fromString at Cookie.php:78. This prevents webhooks and some clients from reaching the app when they (incorrectly) send empty cookies.

Steps to reproduce

  1. Run Expose to share a local Laravel (with Herd) app to the public.
  2. Send a POST request to the tunnel URL with an explicit empty Cookie header
  3. Expose crashes and the tunnel is closed.

Relevant log output

200    GET  / ........................................................................................................................   09:13:07  107 ms
[2025-09-07 11:23:42] production.ERROR: Malformed Cookie header found {"exception":"[object] (Laminas\\Http\\Header\\Exception\\RuntimeException(code: 0): Malformed Cookie header found at phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/laminas/laminas-http/src/Header/Cookie.php:78)
[stacktrace]
#0 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/laminas/laminas-http/src/Headers.php(495): Laminas\\Http\\Header\\Cookie::fromString('cookie:')
#1 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/laminas/laminas-http/src/Headers.php(391): Laminas\\Http\\Headers->lazyLoadHeader(8)
#2 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/Logger/LoggedRequest.php(99): Laminas\\Http\\Headers->current()
#3 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/Logger/LoggedRequest.php(257): Expose\\Client\\Logger\\LoggedRequest->getRequestHeaders()
#4 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/Logger/LoggedRequest.php(50): Expose\\Client\\Logger\\LoggedRequest->getRequestId()
#5 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/Logger/RequestLogger.php(22): Expose\\Client\\Logger\\LoggedRequest->__construct('POST /webhooks/...', Object(Laminas\\Http\\Request))
#6 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/Http/HttpClient.php(51): Expose\\Client\\Logger\\RequestLogger->logRequest('POST /webhooks/...', Object(Laminas\\Http\\Request))
#7 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/ProxyManager.php(107): Expose\\Client\\Http\\HttpClient->performRequest('POST /webhooks/...', Object(Ratchet\\Client\\WebSocket), Object(stdClass))
#8 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/ProxyManager.php(43): Expose\\Client\\ProxyManager->performRequest(Object(Ratchet\\Client\\WebSocket), 'POST /webhooks/...', Object(stdClass))
#9 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/evenement/evenement/src/EventEmitterTrait.php(143): Expose\\Client\\ProxyManager->Expose\\Client\\{closure}(Object(Ratchet\\RFC6455\\Messaging\\Message), Object(Ratchet\\Client\\WebSocket))
#10 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/ratchet/pawl/src/WebSocket.php(72): Ratchet\\Client\\WebSocket->emit('message', Array)
#11 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/ratchet/rfc6455/src/Messaging/MessageBuffer.php(262): Ratchet\\Client\\WebSocket->Ratchet\\Client\\{closure}(Object(Ratchet\\RFC6455\\Messaging\\Message), Object(Ratchet\\RFC6455\\Messaging\\MessageBuffer))
#12 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/ratchet/rfc6455/src/Messaging/MessageBuffer.php(208): Ratchet\\RFC6455\\Messaging\\MessageBuffer->processData('\\x82~\\x04\\x16POST /webho...')
#13 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/evenement/evenement/src/EventEmitterTrait.php(143): Ratchet\\RFC6455\\Messaging\\MessageBuffer->onData('\\x82~\\x04\\x16POST /webho...')
#14 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/react/stream/src/Util.php(71): Evenement\\EventEmitter->emit('data', Array)
#15 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/evenement/evenement/src/EventEmitterTrait.php(143): React\\Stream\\Util::React\\Stream\\{closure}('\\x82~\\x04\\x16POST /webho...')
#16 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/react/stream/src/DuplexResourceStream.php(209): Evenement\\EventEmitter->emit('data', Array)
#17 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/react/event-loop/src/StreamSelectLoop.php(246): React\\Stream\\DuplexResourceStream->handleData(Resource id #1859)
#18 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/react/event-loop/src/StreamSelectLoop.php(213): React\\EventLoop\\StreamSelectLoop->waitForStreamActivity(695656)
#19 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/Factory.php(203): React\\EventLoop\\StreamSelectLoop->run()
#20 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/app/Commands/ShareCommand.php(118): Expose\\Client\\Factory->run()
#21 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/illuminate/container/BoundMethod.php(36): Expose\\Client\\Commands\\ShareCommand->handle()
#22 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/illuminate/container/Util.php(43): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#23 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/illuminate/container/BoundMethod.php(95): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#24 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/illuminate/container/BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(LaravelZero\\Framework\\Application), Array, Object(Closure))
#25 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/illuminate/container/Container.php(696): Illuminate\\Container\\BoundMethod::call(Object(LaravelZero\\Framework\\Application), Array, Array, NULL)
#26 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/illuminate/console/Command.php(213): Illuminate\\Container\\Container->call(Array)
#27 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/symfony/console/Command/Command.php(279): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#28 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/illuminate/console/Command.php(182): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#29 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/symfony/console/Application.php(1094): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/symfony/console/Application.php(342): Symfony\\Component\\Console\\Application->doRunCommand(Object(Expose\\Client\\Commands\\ShareCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#31 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/symfony/console/Application.php(193): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#32 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/laravel-zero/foundation/src/Illuminate/Foundation/Console/Kernel.php(196): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#33 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/vendor/laravel-zero/framework/src/Kernel.php(111): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#34 phar:///Users/claudiuplesa/Library/Application Support/Herd/bin/expose/expose(34): LaravelZero\\Framework\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#35 /Users/claudiuplesa/Library/Application Support/Herd/bin/expose(15): require('phar:///Users/c...')
#36 {main}
"}

creaminds avatar Sep 07 '25 11:09 creaminds

I have the same problem when using Expose and a WordPress application.

[2025-12-04 14:44:14] development.ERROR: Malformed Cookie header found {"exception":"[object] (Laminas\Http\Header\Exception\RuntimeException(code: 0): Malformed Cookie header found at /src/vendor/laminas/laminas-http/src/Header/Cookie.php:78)

danielcivit avatar Dec 04 '25 14:12 danielcivit