zendframework / zend-http

Http component from Zend Framework
BSD 3-Clause "New" or "Revised" License
134 stars 85 forks source link

Requests with integer header keys and string values cause InvalidArgumentExceptions #197

Open aedelstein opened 5 years ago

aedelstein commented 5 years ago

If a user sends a GET request to an endpoint which is run on zend-http and if that GET request has a header key:value pair of the form $integer:$string, (e.g., 2:blah), this will cause the endpoint to throw an InvalidArgumentException.

This appears to be similar to https://github.com/zendframework/zend-http/issues/116 and https://github.com/zendframework/zend-mvc/issues/226 but not quite the same.

Code to reproduce the issue

I don't have a specific code snippet to reproduce this (it affects our entire application) but this seems to be happening because, in zend-http/src/Headers.php, addHeaders() can call addHeaderLine() without a second argument if it sees a header with an integer key:

    public function addHeaders($headers)
    {
        if (! is_array($headers) && ! $headers instanceof Traversable) {
            throw new Exception\InvalidArgumentException(sprintf(
                'Expected array or Traversable; received "%s"',
                (is_object($headers) ? get_class($headers) : gettype($headers))
            ));
        }

        foreach ($headers as $name => $value) {
            if (is_int($name)) {
                if (is_string($value)) {
                    $this->addHeaderLine($value);

Expected results

I'm not sure. Perhaps the header should be ignored? Or that addHeaderLine() should look like $this->addHeaderLine((string)$name, $value);?

Actual results

[18-Nov-2019 16:27:12 UTC] PHP Fatal error:  Uncaught Zend\Http\Header\Exception\InvalidArgumentException: A field name was provided without a field value in <path>/zendframework/zend-http/src/Headers.php:192
Stack trace:
#0 <path>/zendframework/zend-http/src/Headers.php(155): Zend\Http\Headers->addHeaderLine('Mozilla/5.0 (Wi...')
#1 <path>/zendframework/zend-http/src/PhpEnvironment/Request.php(236): Zend\Http\Headers->addHeaders(Array)
#2 <path>/zendframework/zend-http/src/PhpEnvironment/Request.php(84): Zend\Http\PhpEnvironment\Request->setServer(Object(Zend\Stdlib\Parameters))
#3 <path>/zendframework/zend-mvc/src/Service/RequestFactory.php(28): Zend\Http\PhpEnvironment\Request->__construct()
#4 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(703): Zend\Mvc\Service\RequestFactory->__invoke(Object(Zend\ServiceManager\ServiceManager), 'Request', NULL)
#5 <path>/zendframework/zend-mvc-console/src/Service/ConsoleRequestDelegatorFactory.php(34): Zend\ServiceManager\ServiceManager->Zend\ServiceManager\{closure}()
#6 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(738): Zend\Mvc\Console\Service\ConsoleRequestDelegatorFactory->__invoke(Object(Zend\ServiceManager\ServiceManager), 'Request', Object(Closure), NULL)
#7 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(742): Zend\ServiceManager\ServiceManager->Zend\ServiceManager\{closure}(Object(Zend\ServiceManager\ServiceManager), 'Request', Object(Closure), NULL)
#8 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(766): Zend\ServiceManager\ServiceManager->createDelegatorFromName('Request', NULL)
#9 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('Request')
#10 <path>/zendframework/zend-mvc/src/Service/ApplicationFactory.php(34): Zend\ServiceManager\ServiceManager->get('Request')
#11 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(764): Zend\Mvc\Service\ApplicationFactory->__invoke(Object(Zend\ServiceManager\ServiceManager), 'Application', NULL)
#12 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('Application')
#13 <path>/zendframework/zend-mvc/src/Application.php(273): Zend\ServiceManager\ServiceManager->get('Application')
#14 <path>/zend.php(21): Zend\Mvc\Application::init(Array)
#15 {main}
Next Zend\ServiceManager\Exception\ServiceNotCreatedException: Service with name "Request" could not be created. Reason: A field name was provided without a field value in <path>/zendframework/zend-servicemanager/src/ServiceManager.php:771
Stack trace:
#0 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('Request')
#1 <path>/zendframework/zend-mvc/src/Service/ApplicationFactory.php(34): Zend\ServiceManager\ServiceManager->get('Request')
#2 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(764): Zend\Mvc\Service\ApplicationFactory->__invoke(Object(Zend\ServiceManager\ServiceManager), 'Application', NULL)
#3 <path>/zendframework/zend-servicemanager/src/ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('Application')
#4 <path>/zendframework/zend-mvc/src/Application.php(273): Zend\ServiceManager\ServiceManager->get('Application')
#5 <path>/zend.php(21): Zend\Mvc\Application::init(Array)
#6 {main}
  thrown in <path>/zendframework/zend-servicemanager/src/ServiceManager.php on line 771
weierophinney commented 4 years ago

This repository has been closed and moved to laminas/laminas-http; a new issue has been opened at https://github.com/laminas/laminas-http/issues/1.