Security Advisory

ZF2013-01: Route Parameter Injection Via Query String in Zend\Mvc

In Zend Framework 2, Zend\Mvc\Router\Http\Query is used primarily to allow appending query strings to URLs when assembled. However, due to the fact that it captures any query parameters into the RouteMatch, and the fact that RouteMatch parameters are merged with any parent routes, this can lead to overriding already captured routing parameters, bypassing constraints defined in the parents.

As an example, consider the following route definition:

array(
    'user' => array(
        'type' => 'segment',
        'options' => array(
            'route' => '/user/:key',
            'defaults' => array(
                'controller' => 'UserController',
                'action'     => 'show-action',
            ),
            'constraints' => array(
                'key' => '[a-z0-9]+',
            ),
        ),
        'child_routes' => array(
            'query' => array('type' => 'query'),
        ),
    ),
)

If the request URI was /user/foo/?controller=SecretController&key=invalid_value, the RouteMatch returned after routing would contain the following:

array(
    'controller' => 'SecretController',
    'action'     => 'show-action',
    'key'        => 'invalid_value',
)

This would lead to execution of a different controller than intended, with a value for the key parameter that bypassed the constraints outlined in the parent route.

Action Taken

Zend Framework 2.1 introduced changes to the router implementation that now allows passing both query string values and fragment values during URI assembly, effectively obsoleting the original use case of the Query route. As an example, you can now do the following:

$url = $router->assemble(array(
    'name' => 'foo',
), array(
    'query' => array(
        'page' => 3,
        'sort' => 'DESC',
    ), 
    // or: 'query' => 'page=3&sort=DESC'
));

// via URL helper/plugin:
$rendererOrController->url('foo', array(), array('query' => $request->getQuery()));

As such, for versions 2.0.8 and 2.1.4, we have marked Zend\Mvc\Router\Http\Query deprecated. Additionally, we have modified the code in its match() method to no longer pass the query parameters to the RouteMatch, eliminating the possibility of route parameter injection entirely.

Recommendations

If you are using the Query route in Zend Framework 2, we recommend upgrading to Zend Framework 2.0.8 or 2.1.4 immediately.

Other Information

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:

Reporting Potential Security Issues

If you have encountered a potential security vulnerability in Zend Framework, please report it to us at zf-security@zend.com. We will work with you to verify the vulnerability and patch it.

When reporting issues, please provide the following information:

We request that you contact us via the email address above and give the project contributors a chance to resolve the vulnerability and issue a new release prior to any public exposure; this helps protect Zend Framework users and provides them with a chance to upgrade and/or update in order to protect their applications.

For sensitive email communications, please use our PGP key.

Policy

Zend Framework takes security seriously. If we verify a reported security vulnerability, our policy is:

back to advisories