# FriendsOfPHP security-advisories: the YAML data set behind composer audit

> A public-domain database of PHP package vulnerabilities, organised one directory per Composer package and one YAML file per CVE, and the place Composer reads when it tells you a dependency is affected.

**FriendsOfPHP/security-advisories** — A database of PHP security advisories

- Repository: https://github.com/FriendsOfPHP/security-advisories
- Stars: 2,142 · Forks: 331
- Language: PHP
- License: Unlicense
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/friendsofphp-security-advisories

## A data set, not an authority

The README is unusually direct about what this repository is and is not. The database references known security vulnerabilities in various PHP projects and libraries, and it must not serve as the primary source of information for security issues. It is not authoritative for any referenced software. What it offers instead is centralisation, for convenience and easy consumption by tools.

That framing explains the whole design. If the entries were meant to be read as security research, they would need prose, exploit details and remediation guidance. Instead each entry is a small structured record, and the record is only as good as the `link` field that points at the maintainer's own announcement. Composer's audit command is the intended consumer.

The licence matches the intent. The database is described as free and unencumbered software released into the public domain, and the `LICENSE` file in the tree carries the Unlicense. There is no attribution requirement and no copyleft obligation, which is what lets a package manager vendor or mirror it freely. The repository is not archived, the last push is dated 2026-09-25, and it has 2,142 stars and 331 forks.

The four repository topics, composer, packagist, php and vulnerabilities, describe the integration surface rather than the subject matter. This is infrastructure for dependency resolution.

## Checking your own project with composer audit

The consuming side is one command, run from the directory that holds your `composer.json` and `composer.lock`:

```sh
composer audit
```

The README links to Composer's own CLI documentation for the audit command, and that link is the correct place to look at command options such as what to do about abandoned packages or how to filter by severity. The README's job here is only to tell you that the database is what makes the command meaningful.

The mechanism is worth understanding because it explains the data format. Composer already knows every package in your lock file, its exact version, and the version constraints your project declared. The advisory database supplies the missing half: a set of version ranges per affected branch. Intersect the two and you get a definite answer. The repository is also referenced by a second link in the README, to a GitHub Action for the PHP security checker, which is the same idea applied continuously in CI instead of on demand.

So there are two ways to consume this data. `composer audit` is interactive and local, and the security checker action runs the equivalent check on every push. Neither is affected by the accuracy caveat above in a serious way, because a wrong entry produces a false positive or a miss in a tool rather than a false claim in prose.

## One directory per package, one file per CVE

The layout is the simplest part of the contribution process and it is derived from Composer package names. You create a directory named after the Composer name of the software with the issue, so an issue in the Symfony HttpFoundation component lives under `symfony/http-foundation`. The repository tree shows how that scales: top-level directories for `3f/`, `adodb/`, `aws/`, `cakephp/`, `codeigniter/`, `codeigniter4/`, `composer/`, `doctrine/`, `drupal/`, `dompdf/`, `endroid/`, `facade/`, `firebase/`, `fuel/` and dozens more, including scope-prefixed names such as `david-garcia/` and `friendsoftypo3/`.

Inside the directory, each security issue gets one file. The filename should be the CVE identifier, which is the preferred form, or failing that the announcement date followed by an increment, with `2012-12-12-1` given as the example.

The consequence of this layout is worth stating plainly: the repository is a deep hierarchy of small files, which makes it extremely easy to review a single pull request and very hard to get a global view. Nothing in the tree is indexed or summarised at the top level. If you want to know whether a specific package has outstanding advisories, you look in that package's directory. If you want to know what was fixed this week across the whole PHP ecosystem, there is no file in this repository that answers it.

## The five required YAML keys and why each one is strict

Each advisory file is YAML and must contain a specific set of entries. `title` describes the issue in a few words. `link` points at the official announcement, with HTTPS preferred over HTTP. `reference` is a unique identifier for the software, and the only supported scheme is `composer://` followed by the Composer identifier. `branches` is the substantive part, and `cve` is added when a CVE identifier exists.

`branches` maps a branch name, like `2.0.x`, to an object with two keys. `time` is the UTC date and time when the issue was fixed, or null if it is not fixed yet, in the format `2012-08-27 19:17:44`. `versions` is an array of Composer-style constraints such as `['>=2.0.0', '<2.0.17']`.

The `time` field carries an explicit warning in the README: it must be as accurate as possible, because it is used to determine whether a project is affected. That is the one place where sloppiness produces a wrong audit result rather than a cosmetic problem, since it is the timestamp that separates fixed versions from vulnerable ones for consumers without a lock file.

The `versions` constraints being in Composer's own format is the design decision that makes the whole thing work. By speaking the same constraint language the resolver already uses, an advisory needs no separate evaluator, no semver translation layer and no custom parser.

## Validating a contribution, and the subtree split caveat

Before sending a pull request you validate the file against the repository's own rules:

```bash
composer install
php -d memory_limit=-1 validator.php
```

The README notes that the validator has dependencies of its own, which is why `composer install` comes first, and that it runs from the root of the project with the memory limit lifted. The raised memory limit is a fair hint about how much the validator loads at once.

Contributions themselves are deliberately low friction. You can send a pull request or create the file directly through the GitHub interface, which means a maintainer can fix a missing advisory without cloning anything. The README points at existing entries as examples rather than shipping a formal schema document, so the validator is the real specification.

There is one structural edge case called out explicitly. When affected code is reachable through more than one Composer entry, which is what happens with read-only subtree splits of a main repository, the information has to be duplicated across several files. The format deliberately does not reference one advisory from another, so a package split into a dozen read-only mirrors means the same advisory written a dozen times. It is inelegant, and it is the right trade for keeping every file independently parseable.

## Conclusion

This database is not a place to research a vulnerability, and the README says so in its first paragraph: it is not authoritative for any software it references. What it is good for is the narrow job Composer needs done, turning package name plus version range into a yes or no, which is why the contribution format is so strict and why the fixed-at timestamp carries a warning about accuracy. If you want an audit, run `composer audit` against your lock file and follow the link in each advisory to the upstream announcement. If you maintain a PHP package and want its advisory here, open a pull request with one YAML file named after the CVE, placed under the directory matching your Composer name, and run the validator before you send it.

## FAQ

### What is the PHP Security Advisories Database used for?

It is a central listing of known vulnerabilities in PHP projects, stored as YAML files, and its main consumer is the `composer audit` command, which intersects the version ranges it stores with the versions in your lock file. The README is explicit that it must not serve as the primary source of information for a security issue and is not authoritative for any referenced software.

### How do I add a security advisory for a PHP package?

Create a directory named after the Composer package name, then add one YAML file inside it named after the CVE identifier, or after the announcement date plus an increment if there is no CVE. The file needs `title`, `link`, `reference` in the `composer://` scheme, and `branches` with `time` and Composer-style `versions` constraints per branch. Then run `php -d memory_limit=-1 validator.php` from the repository root.

### How do I check my PHP project for known vulnerabilities?

Run `composer audit` from the directory containing your `composer.json` and `composer.lock`. Composer compares the exact versions it has resolved against the version constraints stored in this database and reports the packages that fall inside an affected range. The README also links to a GitHub Action for running the equivalent check in CI.

### Can I rely on this database for the details of a vulnerability?

No, and the README says so directly. Each entry carries a `link` field pointing at the official announcement from the affected project, with HTTPS preferred, and that upstream source is the authoritative one. This database exists to centralise information so tools can consume it, which is why its own text stays brief and why accuracy of the fixed-at timestamp is the field that matters most.

## Sources

- [FriendsOfPHP/security-advisories on GitHub](https://github.com/FriendsOfPHP/security-advisories)
- [Issues](https://github.com/FriendsOfPHP/security-advisories/issues)
- [License: Unlicense](https://github.com/FriendsOfPHP/security-advisories/blob/master/LICENSE)
- [README](https://github.com/FriendsOfPHP/security-advisories/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/friendsofphp-security-advisories
