The Zend Framework community is pleased to announce the immediate availability of Expressive 1.0.0rc3!

You can install it using Composer, using the create-project command:

$ composer create-project zendframework/zend-expressive-skeleton:1.0.0rc3@rc expressive

If you're already using Expressive, read below for how to update your application!

Changes in RC3

RC3 shows a number of improvements, including a number of new components created in order to improve interoperability with other PSR-7 middleware solutions.

New Components

First, we split our routing and templating subcomponents into their own repositories and packages:

These contain the code that was originally in Zend\Expressive\Router and Zend\Expressive\Template (with some additions; see below), and the subcomponents were removed from the Expressive tree entirely. Expressive now depends on these packages. This separation allows users of other PSR-7 middleware stacks to use the routing and templating interfaces, as well as their implementations, within their chosen stack.

Next, we created a new package, zendframework/zend-expressive-helpers. This package contains utility classes and middleware useful to Expressive, but which could be useful to other PSR-7 frameworks as well:

  • Zend\Expressive\Helper\ServerUrlHelper provides a class for generating fully-qualified URIs based on the current request. When you provide a path to the helper, that path will be resolved based on the current request scheme and target. This helper depends on dedicated middleware to seed it with the current request, which is also provided in the package.
  • Zend\Expressive\Helper\UrlHelper provides a class for generating URI paths based on the current RouterInterface instance present, delegating to its generateUri() method. It also has awareness of the matched RouteResult (more on that later), allowing you to generate "self" URIs, as well as URIs with partial parameters based on the currently matched route.

You can read about the new helpers in the documentation.

Fixes and Improvements

RouteResult observers

In order to provide the functionality in Zend\Expressive\Helper\UrlHelper, we needed a way to inform classes of the routing results. To accomplish this, we added the following to the zend-expressive-router package:

  • Zend\Expressive\Router\RouteResultSubjectInterface, which defines a class that will obtain a RouteResult and notify observers; and
  • Zend\Expressive\Router\RouteResultObserverInterface, which defines a class that will be updated with a RouteResult.

Zend\Expressive\Application now implements the RouteResultSubjectInterface, and UrlHelper is an example of an observer.

The documentation now contains information on route result observers, should you want more details on the feature.

A small number of fixes and improvements were also made during the RC3 lifecycle.

Create Middleware Pipelines

Michael Moussa provided a feature to allow specifying not just concrete middleware, but arrays of middleware both when creating routed middleware as well as when adding middleware to the pre/post_routing middleware pipelines.

To illustrate:

// Manually, for pipeline middleware:
$app->pipe('/api', [
    'Authentication',
    'Authorization',
    'ContentNegotiation',
    'Validation',
    'Resource',
]);

// Manually, for routed middleware:
$app->get('/api/resource[/{id:\d+}]', [
    'Authentication',
    'Authorization',
    'ContentNegotiation',
    'Validation',
    'Resource',
]);

// Via configuration, for pipeline middleware:
return [
    'middleware_pipeline' => [
        'pre_routing' => [
            [
                'path' => '/api',
                'middleware' => [
                    'Authentication',
                    'Authorization',
                    'ContentNegotiation',
                    'Validation',
                    'Resource',
                ],
            ],
        ],
    ],
];

// Via configuration, for routed middleware:
return [
    'routes' => [
        [
            'name' => 'api',
            'path' => '/api',
            'middleware' => [
                'Authentication',
                'Authorization',
                'ContentNegotiation',
                'Validation',
                'Resource',
            ],
            'allowed_method' => ['GET'],
        ],
    ],
];

In each case, any individual middleware in the list may be a callable middleware, or the name of a service that resolves as middleware.

This feature should allow creating unique, complex middleware pipelines based on specific routes a snap!

Casting view models to arrays

One feature users of zend-view wanted was the ability to pass ViewModel instances to a renderer. Prior to RC3, if you provided a view model, normalization would destroy any variables stored in the view model due to improper casting. This has now been resolved.

Get the Full RouteResult

The full RouteResult is now injected into the request as the attribute Zend\Expressive\Router\RouteResult.

Fewer Silent Failures

A contributor provided a patch that improves the ApplicationFactory by raising exceptions when key services are missing, instead of silently ignoring them. While this is a small backwards compatibility break, it provides important information that previously led to hard-to-debug issues.

Twig improvements

The zendframework/zend-expressive-twigrenderer package now allows you to register custom extensions. See the 0.3.0 changelog for details (which is the first version introducing this capability).

zend-view improvements

The zendframework/zend-expressive-zendviewrenderer package had a number of usability updates:

  • It now adds the zendframework/zend-i18n package as a dependency, as it's a requirement of the PhpRenderer.
  • It now provides concrete ServerUrlHelper and UrlHelper helper classes, as wrappers around the zendframework/zend-expressive-helpers equivalents. This change allowed reducing dependencies, and now allows the package to be used without Expressive.
  • It now provides a factory for the HelperPluginManager, allowing you to provide your own instance, and thus custom helpers.

Document Creating Custom 404 Handlers

Abdul Malik Ikhsan provided documentation covering how to create a custom 404 handler for your application for logic such as logging. You can read it in the cookbook.

Upgrading

If you're already using Expressive, you'll want to upgrade! To do so, you'll need to make a few changes to your application.

Dependency updates

  • Update zendframework/zend-expressive to ~1.0.0@rc || ^1.0. This will also make it easier to upgrade to the stable version when it comes out.
  • Update any zendframework/zend-expressive-* components to ^1.0. These include your chosen router and template system (if any).
  • Potentially add zendframework/zend-expressive-helpers (at ^1.1), if you plan to use the UrlHelper or ServerUrlHelper. (If you're using the zend-view renderer, you'll already be getting this dependency.)

Configuration changes

The only configuration changes necessary are if you want to use the new helpers. If you won't be, and you're not using zend-view, you can skip this section.

First, add service entries for each to config/autoload/dependencies.global.php:

use Zend\Expressive\Helper;

return [
    'dependencies' => [
        'invokables' => [
            Helper\ServerUrlHelper::class => Helper\ServerUrlHelper::class,
            /* ... */
        ],
        'factories' => [
            Helper\UrlHelper::class => Helper\UrlHelperFactory::class,
            /* ... */
        ],
    ],
];

Next, you'll need to add the ServerUrlMiddleware to the midddleware pipeline. Edit config/autoload/middleware-pipeline.global.php as follows:

use Zend\Expressive\Helper;

return [
    // This section will likely be new:
    'dependencies' => [
        'factories' => [
            Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
        ],
    ],
    // This section existed, but needs edits:
    'middleware_pipeline' => [
        'pre_routing' => [
            // Add the following:
            [ 'middleware' => ServerUrlMiddleware::class ],
            /* ... */
        ],
        'post_routing' => [
            /* ... */
        ],
    ],
];

Once these changes are made, your application should now be ready to use the helpers.

Future

We're very excited about this release! Thanks to a large number of testers and users, we've been able to refine the offering, and improve our ability to interoperate in the PSR-7 ecosystem. We feel this version provides a nice sweet spot for the initial stable features, and anticipate a stable release in the next couple weeks.

If you are testing Expressive — whether for the first time, or updating an existing application — please help us polish the release and get it ready for general availability!

Source

In October, while at ZendCon, I presented a talk on Zend Framework 3 entitled "Components, PSR-7, and Middleware: Zend Framework 3." You can view it online, but this post discusses current status, details some decisions, and points to the work still to be done. It's a long read; grab a warm beverage, maybe some popcorn, and take your time.

Prelude

Zend Framework 3 is not just a new release of the framework. It's an initiative, encompassing a number of strategies and projects. Do not get hung up on when the main Zend Framework repository will be tagged as 3.0; the MVC is just one part of an overall plan. This post details those parts; many of them are already accomplished. Hopefully, by the end of this post, you'll see what you can already leverage, and what you may already be leveraging.

Mirroring my ZendCon presentation, I've broken this out into four primary parts: Components, PSR-7, Middleware, and Zend Framework 3.

Components

Zend Framework was originally envisioned and positioned as a component library that also shipped an MVC framework. Unlike PEAR, it was all-or-nothing; if you wanted a single component, you downloaded the entire framework; if you wanted to use the MVC framework, you downloaded the entire framework. Over time, the MVC became the predominant feature, and most code was written or adapted to ensure the various components worked properly when used with the framework, with very little emphasis on standalone usage.

When we started on ZF2, we essentially continued down this path. However, early in the ZF2 development, Composer emerged in the PHP ecosystem, and we decided to leverage that both for distribution of ZF itself, but also for its components. However, the semi-manual/semi-automated approach we used made components second-class citizens, requiring them to be versioned simultaneously, resulting in slower releases.

As a result, a primary goal of the ZF3 initiatives was to split the components into their own repositories, with their own development cycles; the main Zend Framework repository then becomes a meta-package, defining the individual components as dependencies, but shipping no actual code.

The split took quite some time to orchestrate, but was accomplished in May, with the help of Gianluca Arbezzano and Corley, and released as version 2.5.

I'll be following up this post with some of the benefits we've gained from the split, but the overall point is that the separation will help us improve components more granularly, expand the number of contributors, and accelerate component development.

Composer has been wildly successful. It simplifies and streamlines the ability to manage application dependencies, as well as consume them in your code (by providing a common autoloader for all dependencies). Our observation is that an increasing number of developers and companies are choosing to piece together bespoke frameworks targeted at their business needs using commodity components. Splitting component lifecycles facilitates usage of ZF components in these paradigms.

PSR-7

PSR-7 (meta) defines a set of HTTP message interfaces. PHP Standard Recommendations (PSR) are a product of the Framework Interop Group, which exists to identify existing practices and development approaches, and standardize them, with the goal of increasing interoperability between frameworks and libraries. Composer is the fruit of the very first PSR, PSR-0, which provided a common methodology around autoloading.

PSR-7 exists because PHP, for all its web centricity, does not actually model HTTP messages. Most frameworks have provided message abstraction of one form or another since 2005, but they all differ, which means migrating from one framework or HTTP client library to another — or even one version of such a project to another — requires learning a new system for dealing with HTTP messages.

Interestingly, other languages, including Python, Ruby, and Node.js, do provide common HTTP message abstractions, and the result is that code written targeting HTTP messages will typically work regardless of the framework chosen. This leads to a lot of cross-pollination, and allows developers to pick and choose libraries based on their strengths and features, not on the framework.

Many of us in the PHP community feel that HTTP message abstractions should be a commodity.

PSR-7 accomplishes this, and code targeting PSR-7 can thus be re-used by any framework or project that also consumes PSR-7.

PSR-7 was accepted in mid-May; the same day it was accepted, we released:

We feel that PSR-7 is the future of PHP interoperability when writing HTTP-centric applications, and these components form a foundation for projects that choose to target PSR-7.

Middleware and Expressive

When describing Stratigility in the previous section, I used the term "middleware." What is middleware?

Middleware is, quite simply, code sitting between an incoming HTTP request, and the outgoing HTTP response. There are a number of different middleware signatures floating around (subject for a pending blog post!), but the one we've implemented in Stratigility is:

function (
    ServerRequestInterface $request
    ResponseInterface $response,
    callable $next
) : ResponseInterface

where $next can be used to invoke the next middleware in the system, if any. This same signature is being adopted by a number of emerging PSR-7 centric projects such as Relay, and Slim v3.

Expressive is a new microframework for building PSR-7 middleware applications.

Built on top of Stratigility, Expressive is meant to provide minimal plumbing for your applications. A primary goal is to allow you to choose the components you want, and then to provide minimal wiring to get you started. It provides:

  • typehinting against container-interop allowing you to select a service container from which to pull middleware once matched.
  • a RouterInterface, and several implementations, so you can choose a routing implementation that best suits your application needs.
  • a TemplateRendererInterface, and several implementations, so you can choose a template engine that suits the needs of the middleware you write that may use templating — and allow you to swap out engines seamlessly.
  • an error handling mechanism, and choices for how to handle errors in both development and production.

We leverage Composer's installation hooks to prompt you for your choices (thanks for the contribution, Geert!), so that once you install the Expressive skeleton, you're prepared to start developing immediately.

Expressive is currently in release candidate status, and we hope to finalize a stable release soon!

We like middleware because:

  • it tends to be very focused and small, and thus readily understood.
  • it adapts the Unix philosphy (creating complex behavior by piping messages between single-purpose tools) to HTTP applications.
  • it tends to be quite performant.

Any middleware that targets PSR-7 also gains the ability to interop with any other system targeting PSR-7. This means that the ecosystem for middleware users is not a single framework, but any framework that uses PSR-7. We're already seeing amazing middleware libraries popping up, and these will work across the PHP ecosystem. Providing a middleware microframework via Expressive allows our users to capitalize on this.

Zend Framework 3

For many, "Zend Framework 3" means the MVC framework; as such, much of the above may feel like a sideshow, not the main thrust of the new version. This is a misconception.

We decided early this year that we will not be changing the MVC significantly.

When we went from version 1 to version 2, we did a complete rewrite of the MVC. While the new MVC is architecturally superior, its completely different structure meant there was zero way to automate migration, which left many ZF1 users stranded. We did not want to repeat this mistake.

Additionally, the primary issues around the current MVC are:

  • performance
  • interoperability (specifically, ability to use middleware)

These are things we can tackle, while retaining most, if not all, backwards compatibility.

As such, the primary changes we identified were:

  • zend-servicemanager performance
  • zend-eventmanager performance
  • ability to dispatch PSR-7 middleware
  • reduction of dependencies

ServiceManager

We feel zend-servicemanager offers some unique features that are not found in other containers:

  • lazy services
  • delegator services
  • interface injection (via initializers)
  • abstract factories

As such, there are tremendous reasons to choose it over other containers. However, when you have large object graphs, and if you're heavily using features such as abstract factories and initializers, the design in v2 can become tremendously slow.

Michäel Gallego did some deep analysis of the service manager, and identified ways the performance could be radically improved, providing a hefty patch to do so. The main issue was that much of the code for loading services was checking for state changes in the container; as such, the main thrust of the patch Michäel provided was to have state changes — additions of factories to the container — reconfigure the container, so that pulling from the container becomes cheap. The result is a 4X performance boost that is mostly backwards compatible!

There are a few BC breaks with this change, however, which means any component that provides factories is requiring updates to be compatible. These are mostly minor, and we're currently working on ways we may be able to make code forwards compatible while retaining backwards compatibility.

You can read about the changes in the migration guide.

EventManager

Similarly, zend-eventmanager is a unique offering, providing mechanisms for:

  • intercepting filters
  • subject/observer
  • signal slots
  • events

In order to accomplish this, however, it has a lot of code around checking for changes in shared listeners. Additionally, it has leveraged shared solutions such as the PriorityQueue implementation in zend-stdlib, which provide necessary features, but often at a performance cost.

Michäel Gallego, along with Enrico Zimuel, performed comprehensive profiling, and provided a refactor of the component that resulted in 4X performance benefits!

You can read about the changes in the migration guide. Of particular interest is that the 2.7 version provides forwards compatibility features allowing you to prepare your applications now for version 3!

Dispatching Middleware

As noted in the previous section on PSR-7, we feel that the future of PHP web applications is in middleware. We want users to benefit from the middleware ecosystem, but also to migrate to it. To enable this, we decided to build a MiddlewareListener for zend-mvc.

First, though, we had to build a PSR-7 bridge, to allow translation of the zend-http request and response messages already present in zend-mvc to PSR-7, and vice versa. (We chose not to use PSR-7 directly in zend-mvc, as doing so would require changes anywhere you were previously using the request and/or response objects.) This code can be used now, anywhere you need to do such translations.

With that out of the way, we developed the MiddlewareListener. In v3, this will be registered by default, at a higher priority than the standard DispatchListener. If it detects a middleware key in the route matches, it will pull that middleware from the container and dispatch it, using the PSR-7 bridge; otherwise, it will return early, allowing the DispatchListener to take over.

The MiddlewareListener thus becomes your migration path from the zend-mvc to Expressive or other middleware stacks, but also allows you to compose middleware from the greater ecosystem in your zend-mvc applications!

This feature is available currently on the develop branch of zend-mvc, and will be released with v3 of that component.

Reducing Dependencies

Currently, the framework repository requires every Zend Framework component (except the new ones such as Diactoros, Stratigility, Expressive, and the PSR-7 bridge). This poses a problem: what if we want to update another component earlier than others? How will users then opt-in to such new versions?

As an example, we're pushing back plans for refactoring the filter, validator, input filter, and form components, as the proposed changes will take quite some time. However, not every application needs these facilities, and those that do should be able to selectively upgrade. But if we pin to semantic versions — e.g., ~3.0 — users will not be able to do so until the framework upgrades, making it an all or nothing approach.

As such, we've decided to change the requirements for zend-mvc, the framework repository, and the skeleton to the bare minimum needed for an MVC application. We're still scoping this effort, however, so there's time to get your feedback considered.

This will, of course, affect existing applications. You will need to add in dependencies that previously were assumed. Composer, however, makes these relatively trivial:

$ composer require zendframework/zend-form
$ composer require zendframework/zend-session
$ composer require zendframework/zend-paginator

The more problematic part of this will be registration of abstract factories, plugin managers, etc. We're still working on a plan for that, and encourage you to share any ideas you might have around it.

Documentation

One area where Zend Framework is consistently criticized is its documentation.

  • We don't have enough documentation
  • Documentation isn't updated to reflect new features.
  • Documentation doesn't detail how to consume a component within the MVC framework; or
  • Documentation doesn't detail how to use the component standalone.

With the split to component repositories, we can tackle some of this more easily. We are in the process of moving all documentation into the relevant component repositories, which allows us to block merging of features based on lack of contributed documentation. This will help us keep the documentation up-to-date.

However, we need help writing documentation. We need you to indicate what documentation you feel is missing — and, better yet, contribute that documentation, to help others in the same situation. One reflection I've made is that writing documentation often also points to ways to improve the code; don't discount writing documentation as a non-coding activity!

The documentation migration is being faciliated by Gary Hockin. He is automating the migration via a series of scripts, and also creating issues on each repository indicating common updates that need to happen to fully complete the transition from reStructured Text to Markdown. You can help by perusing the list available at the link below, and submitting pull requests:

At the time of writing, he has not yet run the script over all repositories, but indicates that he should accomplish this feat within the next 10 days; as such, keep checking that link!

Roadmap

As noted, we've made significant progress since announcing the ZF3 initiative in March. We still have a ways to go, however:

  • We're still finalizing changes to Expressive prior to a stable release.
  • We're only halfway through the list of components needing service manager and/or event manager migrations, and could use some assistance completing this task. We cannot do a zend-mvc beta currently until this is done.
  • We're still identifying what components will be considered "core" to the MVC, and could use your feedback.
  • Related, we're still identifying what components will be considered "core" to the framework, if the list is not identical to those in the MVC; again, feedback is welcome.

For a number of considerations, we cannot at this time create a date-based roadmap; we will do releases when code is ready and meets the project quality guidelines. The links above, and in the documentation section, provide ways that you can help; the more help we get, the sooner we can potentially release.

Closing Notes

First, this post was long, and also long overdue. My plan going forward is to provide bi-weekly updates on the Zend Framework blog, so that you, Zend Framework's users and development community, can keep track of progress. In those, I will also be listing areas where we can particularly use contributions. Be aware, however, that with holidays coming up in many countries, that progress will be slow in the short-term.

We're very excited about the Zend Framework 3 initiative. It's a change in direction for the framework, returning to its roots as a component library first, which happens to also provide a full-stack framework.

We see ZF3 as a movement: an end to framework silos, by providing quality, commodity code that can be used everwhere and anywhere. An end to saying "I'm a ZF developer," or "I'm a Laravel developer," and a return to, "I'm a PHP developer." We hope you'll help us complete that journey!

Source

The Zend Framework community is pleased to announce the immediate availability of:

  • Zend Framework 1.12.17
  • Zend Framework 2.4.9

These releases contain security fixes.

Security Fixes

ZF2015-09

ZF2015-09 provides a security hardening patch for users of our word-based CAPTCHA adapters, ensuring better randomization of the letters generated.

This particular issue touches each of the following projects, and was fixed in the versions specified:

  • Zend Framework 1, version 1.12.17
  • Zend Framework 2, versions 2.4.9
  • zend-captcha, versions 2.4.9 and 2.5.2

ZF2015-10

ZF2015-10 addresses potential information disclosure for users of Zend Framework's Zend\Crypt\PublicKey\Rsa support, due to an insecure OpenSSL padding default. The issue is patched in Zend Framework 2.4.9 and zend-crypt 2.4.9/2.5.2.

Changelog

For the full changelog on each version:

Long Term Support

As a reminder, the 2.4 series is our current Long Term Support release, and will receive security and critical bug fixes until 31 March 2018.

You can opt-in to the LTS version by pinning your zendframework/zendframework Composer requirement to the version ~2.4.0.

Visit our Long Term Support information page for more information.

Source

ZF2015-10: Potential Information Disclosure in Zend\Crypt\PublicKey\Rsa\PublicKey

Zend\Crypt\PublicKey\Rsa\PublicKey has a call to openssl_public_encrypt() which uses PHP's default $padding argument, which specifies OPENSSL_PKCS1_PADDING, indicating usage of PKCS1v1.5 padding. This padding has a known vulnerability, the Bleichenbacher's chosen-ciphertext attack, which can be used to recover an RSA private key.

Action Taken

  • Zend\Crypt\PublicKey\Rsa\PublicKey::encrypt() was updated to accept an additional argument, $padding; the default value for this argument was set to OPENSSL_PKCS1_OAEP_PADDING.
  • Zend\Crypt\PublicKey\Rsa\PrivateKey::decrypt() was updated to accept an additional argument, $padding; the default value for this argument was set to OPENSSL_PKCS1_OAEP_PADDING.
  • Zend\Crypt\PublicKey\Rsa::encrypt() was updated to accept an additional optional argument, $padding, allowing the user to specify the padding to use with PublicKey::encrypt().
  • Zend\Crypt\PublicKey\Rsa::decrypt() was updated to accept an additional optional argument, $padding, allowing the user to specify the padding to use with PrivateKey::decrypt().

The above changes represent a backwards-compatibility break, but were necessary to prevent the outlined vulnerability. If you were using Zend\Crypt\PublicKey\Rsa previously, you will likely need to re-encrypt any data you've previously encrypted to use the new padding. This can be done as follows:


$decrypted = $rsa->decrypt($data, $key, $rsa::MODE_AUTO, OPENSSL_PKCS1_PADDING);
$encrypted = $rsa->encrypt($data, $key); // Encrypted using OPENSSL_PKCS1_OAEP_PADDING

The key may have a value of null in each of the examples above.

The following releases contain the fixes:

  • Zend Framework 2.4.9
  • zend-framework/zend-crypt 2.4.9
  • zend-framework/zend-crypt 2.5.2

This advisory was given the CVE identifier CVE-2015-7503

Recommendations

If you use zend-crypt via either Zend Framework 2 or the zendframework/zend-crypt package, and are using the RSA public key functionality, we recommend upgrading to 2.4.9/2.5.2 immediately.

Acknowledgments

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

Source

ZF2015-09: Potential Information Disclosure and Insufficient Entropy vulnerability in Zend\Captcha\Word

In Zend Framework, Zend_Captcha_Word (v1) and Zend\Captcha\Word (v2) generate a "word" for a CAPTCHA challenge by selecting a sequence of random letters from a character set. Prior to this advisory, the selection was performed using PHP's internal array_rand() function. This function does not generate sufficient entropy due to its usage of rand() instead of more cryptographically secure methods such as openssl_pseudo_random_bytes(). This could potentially lead to information disclosure should an attacker be able to brute force the random number generation.

Action Taken

The code used to randomly select letters was updated as follows:

  • In Zend Framework 1.12.17, the methods randBytes() and randInteger() were added to Zend_Crypt_Math. Zend_Captcha_AbstractWord was updated to use Zend_Crypt_Math::randInteger() instead of array_rand() when selecting letters for the CAPTCHA word.
  • In the package zendframework/zend-captcha 2.4.9/2.5.2 and Zend Framework 2.4.9, Zend\Captcha\AbstractWord was updated to use Zend\Math\Rand::getInteger() instead of array_rand() when selecting letters for the CAPTCHA word.

The following releases contain the fixes:

  • Zend Framework 1.12.17
  • Zend Framework 2.4.9
  • zend-captcha 2.4.9
  • zend-captcha 2.5.2

Recommendations

This patch is considered a security hardening patch, and as such, was not assigned a CVE identifier.

Regardless, if you use one of the word-based CAPTCHA adapters in Zend Framework 1 or 2, we recommend upgrading to 1.12.17, 2.4.9, or zend-captcha 2.4.9/2.5.2.

Acknowledgments

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

Source

ZF2015-10: Potential Information Disclosure in Zend\Crypt\PublicKey\Rsa\PublicKey

Zend\Crypt\PublicKey\Rsa\PublicKey has a call to openssl_public_encrypt() which uses PHP's default $padding argument, which specifies OPENSSL_PKCS1_PADDING, indicating usage of PKCS1v1.5 padding. This padding has a known vulnerability, the Bleichenbacher's chosen-ciphertext attack, which can be used to decrypt arbitrary ciphertexts.

Action Taken

  • Zend\Crypt\PublicKey\Rsa\PublicKey::encrypt() was updated to accept an additional argument, $padding; the default value for this argument was set to OPENSSL_PKCS1_OAEP_PADDING.
  • Zend\Crypt\PublicKey\Rsa\PrivateKey::decrypt() was updated to accept an additional argument, $padding; the default value for this argument was set to OPENSSL_PKCS1_OAEP_PADDING.
  • Zend\Crypt\PublicKey\Rsa::encrypt() was updated to accept an additional optional argument, $padding, allowing the user to specify the padding to use with PublicKey::encrypt().
  • Zend\Crypt\PublicKey\Rsa::decrypt() was updated to accept an additional optional argument, $padding, allowing the user to specify the padding to use with PrivateKey::decrypt().

The above changes represent a backwards-compatibility break, but were necessary to prevent the outlined vulnerability. If you were using Zend\Crypt\PublicKey\Rsa previously, you will likely need to re-encrypt any data you've previously encrypted to use the new padding. This can be done as follows:

$decrypted = $rsa->decrypt($data, $key, $rsa::MODE_AUTO, OPENSSL_PKCS1_PADDING);
$encrypted = $rsa->encrypt($data, $key); // Encrypted using OPENSSL_PKCS1_OAEP_PADDING

The key may have a value of null in each of the examples above.

The following releases contain the fixes:

  • Zend Framework 2.4.9
  • zend-framework/zend-crypt 2.4.9
  • zend-framework/zend-crypt 2.5.2

This advisory was given the CVE identifier CVE-2015-7503

Recommendations

If you use zend-crypt via either Zend Framework 2 or the zendframework/zend-crypt package, and are using the RSA public key functionality, we recommend upgrading to 2.4.9/2.5.2 immediately.

Other Information

Acknowledgments

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

Source

ZF2015-09: Potential Information Disclosure and Insufficient Entropy vulnerability in Zend\Captcha\Word

In Zend Framework, Zend_Captcha_Word (v1) and Zend\Captcha\Word (v2) generate a "word" for a CAPTCHA challenge by selecting a sequence of random letters from a character set. Prior to this advisory, the selection was performed using PHP's internal array_rand() function. This function does not generate sufficient entropy due to its usage of rand() instead of more cryptographically secure methods such as openssl_pseudo_random_bytes(). This could potentially lead to information disclosure should an attacker be able to brute force the random number generation.

Action Taken

The code used to randomly select letters was updated as follows:

  • In Zend Framework 1.12.17, the methods randBytes() and randInteger() were added to Zend_Crypt_Math. Zend_Captcha_AbstractWord was updated to use Zend_Crypt_Math::randInteger() instead of array_rand() when selecting letters for the CAPTCHA word.
  • In the package zendframework/zend-captcha 2.4.9/2.5.2 and Zend Framework 2.4.9, Zend\Captcha\AbstractWord was updated to use Zend\Math\Rand::getInteger() instead of array_rand() when selecting letters for the CAPTCHA word.

The following releases contain the fixes:

  • Zend Framework 1.12.17
  • Zend Framework 2.4.9
  • zend-captcha 2.4.9
  • zend-captcha 2.5.2

Recommendations

This patch is considered a security hardening patch, and as such, was not assigned a CVE identifier.

Regardless, if you use one of the word-based CAPTCHA adapters in Zend Framework 1 or 2, we recommend upgrading to 1.12.17, 2.4.9, or zend-captcha 2.4.9/2.5.2.

Other Information

Acknowledgments

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

Source

ZF2015-08: Potential SQL injection vector using null byte for PDO (MsSql, SQLite)

The PDO adapters of Zend Framework 1 do not filter null bytes values in SQL statements. A PDO adapter can treat null bytes in a query as a string terminator, allowing an attacker to add arbitrary SQL following a null byte, and thus create a SQL injection.

We tested and verified the null byte injection using pdo_dblib (FreeTDS) on a Linux environment to access a remote Microsoft SQL Server, and also tested against and noted the vector against pdo_sqlite.

Action Taken

We added null byte filtering in the PDO abstract component Zend_Db_Adapter_Pdo_Abstract. We decided to use the abstract component to prevent null byte injection in all the PDO adapters once we discovered the situation was not specific to pdo_dblib.

We used the PHP's addcslashes to sanitize and properly quote null bytes:


$value = addcslashes($value, "\000\032");

The following releases contain the fixes:

  • Zend Framework 1.12.16

Recommendations

If you use one of the PDO-based adapters in Zend Framework 1, we recommend upgrading to 1.12.16 immediately.

Acknowledgments

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

  • Chris Kings-Lynne, who discovered and reported the issue against the Zend_Db_Adapter_Pdo_Mssql component of ZF1;
  • Enrico Zimuel, who provided the patch.

Source

ZF2015-07: Filesystem Permissions Issues in Multiple Components

As reported by the Doctrine Project, incorrect permissions masks when creating a new directory or file can lead to:

  • Local arbitrary code execution
  • Privilege escalation

Such attacks typically require direct access to a user of the system to exploit, but are dangerous vectors when available.

During an audit of the Zend Framework code base, we found several instances where we were using incorrect permissions masks that could lead to such vulnerabilities.

Action Taken

We identified the following projects/components with vulnerabilities by checking for mkdir() and umask() calls:

  • Zend Framework 2's zend-cache component, specifically the Filesystem storage adapter and CaptureCache pattern.
  • The admin-facing code for zf-apigility-doctrine
  • Zend Framework 1's Zend_Cloud Filesystem storage adapter, Zend_Search_Lucene's filesystem storage, and Zend_Service_WindowsAzure's package scaffolder.

We updated the code as follows:

  • Default privileges for creating directories were set to 0775, and files to 0664.
  • If code allows specifying the permissions mask, we mask it using & ~0002. This means that if you absolutely must allow world-executable privileges, you must extend the class. This leaves the framework secure by default, and is an effort to prevent developers from shooting themselves in the foot.

The following components/libraries were patched, at the version specified:

  • Zend Framework 1, version 1.12.16
  • Zend Framework 2, versions 2.4.8
  • zf-apigility-doctrine, version 1.0.3
  • zend-cache, versions 2.4.8 and 2.5.3

This vulnerability was originally disclosed via the Doctrine project as CVE-2015-5723.

Recommendations

If you use any of the components listed above, we recommend upgrading to one of these versions immediately.

Acknowledgments

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

Source

The Zend Framework community is pleased to announce the immediate availability of:

  • Zend Framework 1.12.16
  • Zend Framework 2.4.8

These releases contain a security fixes.

Security Fixes

ZF2015-07

ZF2015-07 addresses attack vectors that arise due to incorrect permissions masks when creating directories and files within library code.

This particular issue touches each of the following projects, and was fixed in the versions specified:

  • Zend Framework 1, version 1.12.16
  • Zend Framework 2, versions 2.4.8
  • zf-apigility-doctrine, version 1.0.3
  • zend-cache, versions 2.4.8 and 2.5.3

ZF2015-08

ZF2015-08 addresses potential null byte injection of SQL statements issued using Zend Framework's pdo_dblib (FreeTDS) and pdo_sqlite adapters. The issue is patched in Zend Framework 1.12.16.

Changelog

For the full changelog on each version:

In particular, the 2.4.8 release has numerous fixes in the InputFilter, Validator, and Form components introduced to increase stability and reinstate behavior prior to version 2.4.0. At this time, forms and input filters created using code from pre-2.4 should work identically.

We have, however, deprecated the allow_empty and continue_if_empty flags, and provided notes in the changelog that describe alternatives to their usage. We have found that these flags, particularly in combination with the required flag and validators, can lead to unexpected or unintended behavior, often contradictory. Deprecating them will allow us to introduce cleaner solutions in future releases.

Long Term Support

As a reminder, the 2.4 series is our current Long Term Support release, and will receive security and critical bug fixes until 31 March 2018.

You can opt-in to the LTS version by pinning your zendframework/zendframework Composer requirement to the version ~2.4.0.

Visit our Long Term Support information page for more information.

Source