You may have noticed the recent fuss about the compromise of event-stream, a popular NPM package:
This attack raised, again, the problem of the JS dependency cascade: when you install a major project, it comes with hundreds of tiny libraries, sometimes not maintained, and sometimes coming from untrusted sources.
Regarding Symfony, as a maintainer I have the feeling that the Symfony Core Team (carefully) adds dependencies only when strictly necessary. However I had no metrics to prove it. So I checked. Then I compared with other PHP frameworks I’m interested in: Laravel and API Platform.
When installing Symfony 4.1 using the official skeleton, only 20 packages are downloaded (19 when excluding dev dependencies). 16 are directly maintained by the Symfony project, and the 4 others are interfaces from the PHP Framework Interoperability Group:
$ composer create-project symfony/skeleton nb-deps $ composer info | wc -l 20 $ composer info | cut -d/ -f1 | uniq psr symfony
Even when installing the website skeleton, that comes with all features provided by the framework and third party (trusted) packages such as the Doctrine ORM, the Twig templating library or Swift Mailer, only 94 packages (75 when excluding dev dependencies), from 17 different organisations (14 without dev deps) are installed:
$ composer create-project symfony/website-skeleton nb-deps $ composer info | wc -l 94 $ composer info | cut -d/ -f1 | uniq doctrine easycorp egulias facebook fig jdorn monolog nikic ocramius phpdocumentor psr sensio swiftmailer symfony twig webmozart zendframework
Among these vendors, 7 are directly maintained by members (or former members) of the Symfony Core Team (easycorp, monolog, sensio, swiftmailer, symfony, twig, webmozart) and 2 are from the FIG. All these few libraries, except maybe jdorn/sql-formatter, are actively maintained, by prominent and well known members of the PHP community.
A minimal installation of the server part (the one written in PHP) of the API Platform framework contains only 27 packages (26 without dev deps) from 5 vendors.
$ composer create-project symfony/skeleton nb-deps $ composer require api-platform/core $ composer info | wc -l 27 $ composer info | cut -d/ -f1 | uniq api-platform doctrine psr symfony willdurand
When installing the API pack, that provides all features you can expect from an advanced web API (hypermedia support, automatic persistence with the Doctrine ORM support, automatic generation of human-readable documentation, CORS support, authorisation rules…), 57 packages (56 without dev deps) from 10 vendors are shipped.
$ composer create-project symfony/skeleton nb-deps $ composer require api $ composer info | wc -l 57 $ composer info | cut -d/ -f1 | uniq api-platform doctrine jdorn nelmio phpdocumentor psr symfony twig webmozart willdurand
The default installation of Laravel (that is somewhat similar in term of features to the Symfony website skeleton) comes with 72 packages (39 when excluding dev deps) from 35 vendors (21 when excluding dev deps).
$ laravel new nb-deps $ composer info | wc -l 72 $ composer info | cut -d/ -f1 | uniq dnoegel doctrine dragonmantank egulias erusev fideloper jakub-onderka laravel league monolog nesbot nikic opis paragonie psr psy ramsey swiftmailer symfony tijsverkoyen vlucas
The number of maintainers you have to trust when using Laravel is just a bit larger than when using Symfony, but again it’s still a bunch of people that are well known in the PHP community, and who may fit in a single room.
In comparison, a default installation of React using Create React App – that is more similar to the minimal Symfony skeleton than to fully-featured frameworks such as the Symfony website skeleton or Laravel – comes with 809 packages, most of them being maintained by different teams or individuals.
Another main difference is that most JS libraries are distributed as compiled and minified builds. Therefore it’s very difficult to guarantee that what is shipped and executed behaves exactly the same way than the code in the sources. In PHP, the source of the libraries are used directly, without intermediate obfuscation. PHP builds are easy to reproduce, it helps a lot when auditing.
Of course, it doesn’t mean that major PHP frameworks are immune to this kind of attacks and – as any IT project – they also have their own security issues. However, the amount of third party code installed and the chain of trust you have to rely on is more under control than in the JS world.
By the way, you’d better actively monitor the security vulnerabilities that may affect your PHP projects.