View Tutorial Metadata Edit Content Revision History Add to Watchlist Add New Tutorial Zend Framework plugins and the Front Controller throwException setting

How does the ZF Front Controller throwExceptions setting influence its plugins

Introduction

Zend Framework features a set of MVC components that allow you to rapidly develop a web application by dividing functionality into separate controllers. Controllers can be grouped in modules, but we won't discuss about that in this tutorial.

A principal actor of the MVC pattern is the Front Controller, which interprets the HTTP request. Depending on the Get and Post parameters, it instances a specific controller. Afterwards, it calls one of its methods (called an action). This operation is called "dispatching". In a dispatch, the (module, controller, action) tuple determines which specific piece of code is going to be executed for the current request.

Additional front controller functionality can be added using the plugin system. One of the default plugins coming with Zend Framework is the ErrorHandler (Zend_Controller_Plugin_ErrorHandler class). If an exception was thrown by the current dispatch, this plugin will take care of displaying an error page.

In this tutorial, the security implications of the thrownExceptions setting will be considered.

The dispatch process - an overview

The front controller keeps a list of all the loaded plugins (Plugin broker). When a dispatch is made, the plugins go through the following flow:

  1. routeStartup: each plugin is notified that the request is about to be checked against existing routes.
  2. routeShutdown: the plugins are notified that the route has been determined. The request parameters are now defined
  3. dispatchLoopStartup: the dispatch loop is about to start.
  4. preDispatch: the plugins are notified that a dispatch is about to occur.
  5. postDispatch: notification occuring after the dispatch.
  6. If we still have a request to dispatch, go to step 4 (either a plugin or the action itself has determined that a new dispatch is required)
  7. dispatchLoopEnd: notify the plugins that the dispatch loop has ended.

Case study - an ACL plugin

To solve the ACL problem, one of the things you can do is write a plugin for the Front Controller.

Basically what ACL does is: it check if the current user has the permission to access the resources they requested. In the preDispatch handler, we have available all the information we need about the request to decide if we should allow the current request to continue.

Okay, let's begin - here's the skeleton for the plugin:

class MyApp_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
 
    }
}

To register this class as a plugin, the simplest way is to add this to your application ini configuration file:

resources.frontcontroller.plugins.0 = MyApp_Plugin_Acl

Now, depending on what values $request has in it, you have to decide whether to continue the dispatch or not. Specific details about ways in which to be done will be elaborated at a later time, but in short you have to use the redirect helper. Here's an ACL that will block all requests, and redirect to the index page (unless the request is for the index page itself; this is necessary in order to prevent an infinite redirection):

class MyApp_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        if (($request->getParam('controller') == 'index') &&
            ($request->getParam('action') == 'index'))
            return;
 
        $this->_redirectNoAuth();
    }
 
    protected function _redirectNoAuth()
    {
        $redir = Zend_Controller_Action_HelperBroker::getStaticHelper(
            'Redirector');
 
        $redirParams = array('controller' => 'index', 'action' => 'index');
        $redir->setGotoRoute($redirParams, 'default', true);
        $redir->redirectAndExit();
    }
}

Note that the redirector plugin redirectAndExit method will halt the current PHP script execution. This way, no further action will be executed, and the dispatch is completely interrupted.

The point is, be aware that there is a very important Front Controller setting, called throwExceptions. Its default value is false. If it's false, then if inside the preDispatch an exception is thrown, it's possible that your security is compromised: the exception will be catched by the frontController, and the dispatch will continue, executing potentially dangerous code.

It's therefore more secure to set throwException to true. In your .ini configuration file, you can do it like this:

resources.frontcontroller.throwExceptions = 1

This way, the dispatch will also be interrupted if an Exception is thrown inside the ACL plugin.

This tutorial is based on Zend Framework 1.8.4.

References: Zend Framework Documentation

Only plain text supported.

Optional

Required - will be kept private

Optional

 
 

Rating: (0+, 0-) In: PHP 5, Zend Framework