Discover Security Advisories with Composer’s audit command

Did you know that October is Cyber Security Awareness month, and that this year already marks its 21st anniversary? This collaborative effort between government and industry aims to raise awareness of online risks and to share important safety tips. These campaigns focus on basic best practices, such as protecting your account with strong passwords and multifactor authentication, recognizing phishing attempts and always upgrading software to the latest version. This is a great initiative, and educating end-users on how to be extra careful online benefits us as developers directly. If users feel comfortable with these mechanisms, deploying them becomes a no-brainer.

Rolling out strong authentication and access control was ranked as the top priority for most developers, according to Zend's 2024 PHP Landscape Report. The second and third priorities are implementing secure coding practices and applying security patches in application dependencies regularly.

Luckily, the PHP community provides plenty of tools and resources to help you manage both these priorities efficiently. To celebrate Cyber Security Awareness month, we’ll take a closer look at how Composer and Packagist help you manage reported vulnerabilities in your software supply chain.

Manage Security Advisories for PHP packages 

Composer's audit command tells you if there are security vulnerability advisories for any installed packages in your project. The audit command will exit with a non-zero return value that represents the number of matched advisories, which makes it perfectly suited for your CI pipeline. If the audit command discovers problems, the non-zero exit code will trigger your build to fail, unless otherwise configured. It's the easiest way to prevent known vulnerabilities from getting installed in your live environment. 

Alternatively, there's an --audit flag on the composer install command itself to install and run an abbreviated audit automatically. With this flag enabled, composer also exits with a non-zero status code if security advisories are found. 

If you run composer update or require a new package, Composer runs the abbreviated audit by default, to make sure you are aware of potential vulnerabilities.

Abbreviated audit message

This abbreviated audit looks inside the package’s metadata served up by Packagist.org, which only contains advisory IDs and their affected version ranges. To figure out the actual details, use composer audit

The audit command outputs the package name, the range of affected versions, its severity, a link to the advisory and a CVE identifier if there is one. It queries this information directly from the Packagist.org Security Advisory API, which is publicly available on our public Composer repository. When we first launched this API at Packagist.org, it used FriendsOfPHP/security-advisories as its only source. We’ve since expanded this database by importing advisories from the GitHub Advisory Database as well.

We’ll aggregate the data from these two sources and deduplicate advisories into a single entry if duplicates are found. By combining these two datasets we cast a wide net to quickly catch potential security threats from the world of open source PHP packages. 

Other Composer repositories than Packagist.org can provide this information to Composer as well. For example, Drupal’s own repository, packages.drupal.org, provides security advisories for the packages hosted there. If you require a Drupal module version that has a known vulnerability, Composer will also warn you about it!  

On Packagist.org, you can consult these advisories directly in the user interface too. Vulnerable versions are marked with a warning sign and you can access all reported advisories for a package by browsing to the Security section. For example, here are the security advisories for doctrine/orm:

Known security advisories for doctrine/orm on Packagist.org

You can also use the Security Advisories API to consume this information directly in your own packages and tooling. 

An important feature of the audit command that goes hand in hand with security advisories, is warning you when the maintainer has marked a package as abandoned. Abandoned packages will no longer receive security patches, so it’s paramount that you replace them with their suggested counterparts wherever possible. Since Composer 2.7, the audit command exits with a non-zero status code if your project relies on abandoned packages. You can configure this behavior in your composer.json.

Abandoned package reported by the audit command

These security advisories are managed and curated by the PHP community. And of course, there are other great tools available to work with the information in FriendsOfPHP/security-advisories. Symfony's check:security command can be used in CI pipelines, too, to check if you are requiring packages with known vulnerabilities. If you require the Roave/SecurityAdvisories package in your project, it conflicts with all package versions listed in the security-advisories repository. That prevents package versions with known advisories from selection for your project during a composer update. 

Private Packagist's Security Monitoring feature automatically keeps track of security vulnerabilities in your Composer project dependencies for you. This feature is also made possible by the same Packagist.org Security Advisory API. The main advantage is, that you will receive an alert as soon as a new vulnerability is disclosed for a package version that you are using in your projects, rather than finding out about it when running composer audit the next time. This functionality is available to all our customers out of the box: all you have to do is add your project with a composer.lock file as a regular package. 

A Bigger Open-Source Vulnerability Ecosystem

Security vulnerabilities in software continue to pose a significant threat, whether we like it or not. It follows that the methods to efficiently share information about known issues need to keep evolving too. The system to identify vulnerabilities that we're all familiar with, the Common Vulnerabilities and Exposures (CVE) system, released their new CVE JSON 5.0 format two years ago. This format adds several new data fields, to include severity scores, affected product lists, additional references and much more. The JSON 4.0 format has been phased out this year. 

The CVE system only concerns itself with identifying vulnerabilities, it's not a database. Open-source databases have appeared to help developers track reported vulnerabilities and aggregate information from multiple sources, as we are doing with the Packagist.org Security Advisory API for PHP packages, and Drupal does for Drupal modules and core packages at packages.drupal.org, for example. Each of them is focused on specific software tools, ecosystems and communities, so there is still a need to bring all of this data together. 

The Open Source Vulnerability (OSV) project, launched by Google in 2021, presents the OpenSSF OSV format to create an open and distributed security advisory resource at osv.dev. The format aims to provide actionable data on vulnerabilities in a machine-readable format, with the explicit goal of mapping disclosures to open-source versioning schemes. 

This project is developed in collaboration with open-source communities and covers a broad range of data sources today, and boasts coverage across a wide range of ecosystems, including npm packages, Rubygems, Python and NuGet. Packagist is also listed, but this data currently comes only from the Github Advisory Database, and not our more complete API. 

How is your team handling security advisories?

Which processes and tools is your team implementing to track security vulnerabilities and handle updates, and which sources do you feel are missing in the Packagist.org Security Advisory API? We’d love to hear your opinion, be sure to let us know!