<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title><![CDATA[The PHP Foundation]]></title>
    <link href="https://deploy-pr-320--thephpfoundation.netlify.app/atom.xml" rel="self"/>
    <link href="https://deploy-pr-320--thephpfoundation.netlify.app/"/>
    <updated>2026-08-31T12:57:13+00:00</updated>
    <id>https://deploy-pr-320--thephpfoundation.netlify.app/</id>
        <generator uri="http://sculpin.io/">Sculpin</generator>
            <entry>
            <title type="html"><![CDATA[So You Received a Security Report. Now What?]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/19/so-you-received-a-security-report-now-what/"/>
            <updated>2026-08-19T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/19/so-you-received-a-security-report-now-what/</id>
            <content type="html"><![CDATA[<p><strong>A guide for PHP project maintainers, from the PHP Foundation Ecosystem Security Team</strong></p>

<blockquote>
  <p>You maintain a PHP project. Someone (maybe Volker from the PHP Foundation, maybe an
  independent researcher) has just told you that your project may have a security
  vulnerability. You might be feeling overwhelmed, or unsure whether you can trust the
  report, or simply unsure what the correct next step is.</p>
  
  <p>Take a breath. <strong>Nothing bad has happened.</strong> A report is not a breach. It is a
  head start: someone is telling you privately about a potential problem. You have
  time to validate it, assess it, and you get to decide what to do next. This guide
  walks you through the whole process, and it ends with concrete steps to make your
  project more resilient for the next time.</p>
  
  <p>And at any point where you get stuck: <strong>you are not alone.</strong> You can always ask the
  Ecosystem Security Team for help. Contact details are at the <a href="#10.-getting-help">end of this
  guide</a>.</p>
</blockquote>

<hr />

<h2 id="how-to-use-this-guide">How to use this guide</h2>

<ul>
<li><strong>Do not read it front to back.</strong> Jump to the stage you are at. Each section starts
with a short "You are here if…" signpost.</li>
<li><strong>Expect to come back over several days.</strong> Handling a security report properly
usually takes more than one sitting, and that is fine.</li>
<li><strong>If you only have five minutes right now,</strong> read the <a href="#cheatsheet">Cheatsheet</a> and
section <a href="#1.-do-not-panic-and-do-not-go-public">1</a>.</li>
</ul>

<p>A word on your authority before we start: <strong>you are the maintainer.</strong> You decide what
is in scope, what the timeline is, and whether a report is valid. Handling a report
well does not mean dropping everything or working weekends. It means following a small
number of steps in the right order, at a pace you can sustain. You do not owe anyone
heroics; see <a href="https://mikemcquaid.com/open-source-maintainers-owe-you-nothing/">Open Source Maintainers Owe You
Nothing</a>.</p>

<hr />

<h2 id="cheatsheet">Cheatsheet</h2>

<p>The whole process on one screen. Details in the numbered sections below.</p>

<ol>
<li><strong>Don't panic, don't go public.</strong> Keep the vulnerability private until a fix is
released. → <a href="#1.-do-not-panic-and-do-not-go-public">§1</a></li>
<li><strong>Acknowledge the report</strong> within a few days, even before you have assessed it.
→ <a href="#2.-acknowledge-the-report">§2</a></li>
<li><strong>Triage:</strong> understand the claim, then decide: valid, invalid, or out of scope.
→ <a href="#3.-triage-the-report">§3</a></li>
<li><strong>Reproduce safely.</strong> Never run proof-of-concept code on your own machine; use an
isolated environment. → <a href="#4.-handle-proof-of-concept-code-safely">§4</a></li>
<li><strong>Fix privately.</strong> Use a temporary private fork; do not push to any public branch.
→ <a href="#5.-prepare-the-fix-privately">§5</a></li>
<li><strong>Write the advisory.</strong> For Composer packages, three fields decide whether the
tooling works: set the ecosystem to <strong>Composer</strong>, use the exact Packagist package
name, and give precise affected-version ranges. Composer will actively <strong>block</strong>
installation of the versions you list.
→ <a href="#6.-write-the-github-security-advisory">§6</a></li>
<li><strong>Publish in the right order:</strong> merge → tag &amp; release → publish the advisory →
submit it to FriendsOfPHP → announce.
→ <a href="#7.-coordinate-the-release-and-publication">§7</a></li>
<li><strong>Wrap up:</strong> credit the reporter, check older branches, do a short retrospective.
→ <a href="#8.-wrap-up">§8</a></li>
<li><strong>Improve your posture</strong> so the next report is easier: SECURITY.md, private
vulnerability reporting, 2FA, hardened CI. → <a href="#9.-improving-your-security-posture-for-the-long-term">§9</a></li>
<li><strong>Ask for help</strong> whenever you are unsure. → <a href="#10.-getting-help">§10</a></li>
</ol>

<hr />

<h2 id="1.-do-not-panic-and-do-not-go-public">1. Do not panic and do not go public</h2>

<p><em>You are here if: a report just landed and your pulse went up.</em></p>

<p>The single most important principle is <strong>coordinated disclosure</strong>: the details of a
vulnerability stay private until a fixed version exists and users can protect
themselves. The moment the details are public, every attacker in the world has them,
and your users do not yet have a fix. So until you publish:</p>

<ul>
<li><strong>Do not</strong> open a public issue about it, reference it in a public pull request, or
mention it in a public commit message.</li>
<li><strong>Do not</strong> push a fix to <code>main</code> or any public branch. A commit titled "fix SQL
injection in login handler" <em>is</em> the disclosure.</li>
<li><strong>Do not</strong> post the details on social media, a blog, or a mailing list, and be
careful with vague teasers, which invite people to go looking. Announcing an
upcoming security release is a legitimate practice that many projects follow, so
that users can plan to update quickly; if you do it, keep the announcement to the
date and the fact that a security release is coming, never the component, the
symptom, or the versions involved.</li>
<li><strong>Do not</strong> go silent on the reporter either. Silence is how well-meaning reporters
become frustrated reporters who eventually publish on their own.</li>
</ul>

<p>Also worth internalizing early: <strong>a report is a claim, not a verdict.</strong> It may be a
serious finding, a minor issue, a duplicate, a bug without security impact, or simply
wrong. Part of your job in the next steps is to find out which, and <em>you</em> make that
call, ideally in dialogue with the reporter.</p>

<p>If the report came from the PHP Foundation Ecosystem Security Team, it has already
been through triage and usually comes with a reproducer. That raises the odds it is
real, but it does not take the decision away from you.</p>

<h2 id="2.-acknowledge-the-report">2. Acknowledge the report</h2>

<p><em>You are here if: you have read the report once and have not replied yet.</em></p>

<p>Reply quickly, even if you have nothing substantial to say yet. A short message buys
you time and goodwill:</p>

<blockquote>
  <p>Thanks for the report. I've received it and will look into it as soon as I can.
  I maintain this project in my spare time. I'll get back to you here.</p>
</blockquote>

<p>That is genuinely all it takes. If you already know you can keep a commitment, adding
a timeframe ("please allow up to two weeks for a first assessment") is a courtesy to
the reporter, but only promise what you can meet: "two weeks" kept is better than
"tomorrow" broken. If the report arrived by email but your
repository has <a href="https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability">GitHub Private Vulnerability
Reporting</a>
enabled (see <a href="#9.-improving-your-security-posture-for-the-long-term">§9</a>), this is a
good moment to move the conversation there: it keeps the discussion and the patch in
one private place. Do not expect it to do your release planning, though — an advisory
has no field for an embargo or a disclosure date, so the timeline is something you and
the reporter agree on in the conversation and then keep to.</p>

<h2 id="3.-triage-the-report">3. Triage the report</h2>

<p><em>You are here if: you have acknowledged the report and now need to decide what it is.</em></p>

<p>Read the report carefully and try to answer four questions:</p>

<ol>
<li><strong>What is the claimed weakness?</strong> (e.g. SQL injection, path traversal, insecure
deserialization, often given as a <a href="https://cwe.mitre.org/">CWE</a> identifier)</li>
<li><strong>Who can trigger it, and from where?</strong> Does it require an authenticated admin, or
can any anonymous user on the internet trigger it? Does it require unusual
configuration?</li>
<li><strong>What can an attacker actually achieve?</strong> Reading data, modifying data, executing
code, denial of service?</li>
<li><strong>Which versions are affected?</strong> Including older major and minor versions that
people still use.</li>
</ol>

<p>The answers determine everything downstream: severity, urgency, and what the fix and
advisory should say. Three notes from practice:</p>

<ul>
<li><strong>Ask questions.</strong> A good reporter would rather answer three clarifying questions
than watch you guess. If the threat model is unclear ("is this exploitable if the
attacker controls that config value? In my project, they never do"), say so. That
discussion is the most valuable part of triage.</li>
<li><strong>"Works as designed" is a legitimate answer.</strong> If exploiting the issue requires the
attacker to already have capabilities that your documented security model says are
trusted, it may not be a vulnerability in your project. Explain your reasoning to
the reporter; if they disagree, the Ecosystem Security Team can act as a neutral
second opinion.</li>
<li><strong>A real bug without security impact is still worth fixing</strong>, just through your
normal, public process, without an advisory.</li>
</ul>

<p>If the volume or quality of reports is a problem in itself (for example, a flood of
low-effort AI-generated reports), that is exactly one of the things the Ecosystem
Security Team exists to help with. Forward them; do not let them eat your motivation.</p>

<h2 id="4.-handle-proof-of-concept-code-safely">4. Handle proof-of-concept code safely</h2>

<p><em>You are here if: the report includes a script, a payload, a crafted file, or
step-by-step exploitation instructions.</em></p>

<p>This section exists because it is the mistake with the worst possible failure mode.</p>

<p><strong>Never run proof-of-concept code directly on your own machine.</strong> Not "just this
once", not because the reporter seems trustworthy, not because you skimmed the code
and it looked fine. Your development machine holds your SSH keys, your GPG keys, your
Packagist and GitHub credentials, your password manager, and, if you use one, your
authenticated AI coding agent. A malicious or merely careless PoC that runs with your
user account can compromise all of it. For a maintainer, that is not just a personal
problem: <strong>your credentials are a supply-chain attack on everyone who installs your
package.</strong></p>

<p>And remember what a PoC <em>is</em>: a program written by a stranger, designed to break
software. Treat it with exactly the suspicion that description deserves. Even an
honest reporter's PoC may delete files, open network connections, or hammer your CPU
as a side effect of demonstrating the bug.</p>

<p>Instead, reproduce in an <strong>isolated, disposable environment</strong>. The best one is the one
you will actually use, so start at the top of this list and only move down if the
issue demands it:</p>

<ul>
<li><strong>A microVM sandbox</strong> is the sweet spot: roughly as convenient as a container, but
running its own kernel instead of sharing the host's, so the boundary is enforced by
hardware. <a href="https://docs.docker.com/ai/sandboxes/">Docker Sandboxes</a> (<code>sbx</code>) gives
each sandbox its own filesystem, network stack, and Docker daemon, with network
access denied by default. Benjamin Eberlei describes <a href="https://www.beberlei.de/post/sbx-sandboxed-claude-complete-with-php-and-tools">a ready-made sbx setup with
PHP, Composer, and the usual
extensions</a>
that you can lift straight into this workflow.</li>
<li><strong>A container</strong> (Docker/Podman) is convenient for typical PHP-level issues and fine
for most web-application-class vulnerabilities. How much isolation you get depends
on where you run it: on Linux, containers share the host kernel, so anything that
smells like memory corruption, native extensions, or kernel interaction deserves a
stronger boundary. On macOS and Windows, Docker Desktop and OrbStack already run
your containers inside a lightweight Linux VM, so a kernel boundary sits between the
container and your actual machine.</li>
<li><strong>A well-secured virtual machine</strong> is the belt-and-braces option: a fresh VM with a
current OS, no credentials or personal data inside, no shared folders into your host,
clipboard sharing disabled, and a snapshot taken <em>before</em> you run anything so you can
roll back afterwards. If the PoC does not need internet access, disable networking
entirely, or restrict it to host-only.</li>
<li><strong>A cloud throwaway</strong> (a short-lived VM at any provider, destroyed afterwards) works
too, as long as no credentials of yours live on it.</li>
</ul>

<p>Inside the isolated environment, the workflow is simple: check out the affected
version of your project, install dependencies, run the PoC, observe. Read the PoC
before running it. Not as a substitute for isolation, but because understanding
<em>how</em> it triggers the bug is exactly the insight you need for the fix and for the
regression test. In fact, this is the natural moment to turn the reproducer into a
failing test (<a href="#5.-prepare-the-fix-privately">§5</a>). Many maintainers treat "I have a
test that fails" as the point at which they accept a report, on the grounds that you
cannot accept what you cannot reproduce.</p>

<p>Two closing rules for this section:</p>

<ul>
<li><strong>Crafted input files are code.</strong> A "harmless" <code>.phar</code>, image, XML document, or
serialized payload attached to a report is an exploit delivery vehicle by
definition. The same isolation rules apply to opening or parsing them.</li>
<li><strong>If you cannot reproduce safely, ask for help</strong> instead of taking the shortcut.
Building reproducers in isolated environments is one of the Ecosystem Security
Team's core services.</li>
</ul>

<h2 id="5.-prepare-the-fix-privately">5. Prepare the fix privately</h2>

<p><em>You are here if: the issue is confirmed and you are ready to write code.</em></p>

<p>GitHub Security Advisories give you a <strong>temporary private fork</strong> for exactly this
purpose. On the advisory page, click <em>"Start a temporary private fork"</em>. Then:</p>

<ol>
<li>Do all of the work in the private fork and open the pull request <strong>there</strong>, never
against your public repository.</li>
<li><strong>Write the regression test first.</strong> A test that fails on the vulnerable code is
the proof that you have really understood and reproduced the issue, and once the
fix is in you can no longer watch it fail. If you built a reproducer during triage
(<a href="#4.-handle-proof-of-concept-code-safely">§4</a>), you already have most of it;
distill it into a safe, minimal test case that demonstrates the <em>condition</em> rather
than shipping a working exploit. This is the part of the work that keeps paying
off: the bug can never quietly come back.</li>
<li><strong>Then write the fix</strong>, and keep commit messages neutral while working; the
advisory will tell the full story later. (Referencing the GHSA ID in the final
commit is fine, since it only resolves to something public after publication.)</li>
<li><strong>Sweep for the same class of bug</strong> before you go any further. Publishing an
advisory puts a spotlight on that weakness class, for human readers and for the
people pointing LLMs at your code, so you want to be reasonably confident that the
same mistake is not sitting three files over, waiting to be found the day after
you publish.</li>
<li>Invite the reporter as a collaborator on the advisory and let them verify the fix.
They already have a working reproducer, so it costs them little. How much weight
their confirmation carries is your judgement call: a researcher who handed you a
precise reproducer is the best-qualified person to confirm the hole is closed,
while a report generated in bulk by a tool is not.</li>
<li>Decide <strong>which versions</strong> get the fix. If you still support older major versions,
users on those versions deserve a patched release too, or an explicit statement in
the advisory that they must upgrade. Severity, the age of the older version, and
the effort a backport would take should all feed into that decision.</li>
</ol>

<p>Gotchas that bite first-timers:</p>

<ul>
<li>CI does not run in temporary private forks. Run your test suite locally (in a safe
environment) before merging.</li>
<li>Don't <code>git push --no-verify</code> out of habit. Hooks that scan for secrets or enforce
checks exist for days exactly like this one.</li>
<li>The temporary private fork <strong>does not outlive the advisory</strong>: depending on where you
are in the process, publishing removes it, or GitHub asks you to delete it before it
lets you publish. Either way, make sure everything you need (the commits, the
discussion outcomes) has landed somewhere permanent first.</li>
<li><strong>Do not fix silently.</strong> A patch released without an advisory leaves every
downstream user blind: <code>composer audit</code> won't warn them, Dependabot won't open a PR,
and most people do not update their dependencies often, so they stay vulnerable
until they happen to. The advisory is not an admission of failure; it is the
mechanism by which your fix actually reaches people.</li>
</ul>

<h2 id="6.-write-the-github-security-advisory">6. Write the GitHub Security Advisory</h2>

<p><em>You are here if: the fix exists and you are filling in the advisory form.</em></p>

<p>You create the advisory in your repository under <strong>Security → Advisories → New
draft security advisory</strong>. The click-by-click walkthrough of that form (every field,
the CVSS calculator, adding credits, adding multiple affected products) is GitHub's
<a href="https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/fix-reported-vulnerabilities/create-repository-advisory">Creating a repository security
advisory</a>.
(If the report arrived via private vulnerability reporting, the draft advisory
already exists; you edit that one rather than creating a new one.) This section
focuses on the part the walkthrough cannot do for you: what to put <em>into</em> the fields.</p>

<p>The advisory is a machine-readable document as much as a human-readable one. Tools
across the ecosystem, among them the <a href="https://github.com/advisories">GitHub Advisory
Database</a>, <a href="https://osv.dev/">OSV.dev</a>, Dependabot,
Packagist, and <code>composer audit</code>, consume it to warn your users automatically. Getting
the metadata right is what makes that machinery work.</p>

<p><strong>For PHP packages installable via Composer, the crucial details are:</strong></p>

<ul>
<li><strong>Ecosystem: select <code>Composer</code>.</strong> Not "Other", not "GitHub Actions", not left empty.
Only advisories filed under the Composer ecosystem are matched against
<code>composer.json</code>/<code>composer.lock</code> files, which is what makes <code>composer audit</code> and
Dependabot alerts fire for your users.</li>
<li><strong>Package name: the exact Packagist name</strong>, in <code>vendor/package</code> form. For example
<code>phpunit/phpunit</code>, not <code>PHPUnit</code> and not the GitHub repository slug if it differs.
A typo here silently breaks the matching. The check takes five seconds: append what
you typed to <code>https://packagist.org/packages/</code> and it must land on your package,
the way <a href="https://packagist.org/packages/phpunit/phpunit">packagist.org/packages/phpunit/phpunit</a>
does.</li>
<li><strong>Affected version ranges: precise and Composer-flavored</strong>, e.g.
<code>&gt;= 10.0.0, &lt; 10.5.17</code>, and one <em>Affected product</em> entry per affected release
series if you patched several (a single field cannot hold multiple ranges). The
exact syntax has non-obvious rules (supported operators, spacing, how suffixes
like <code>-beta1</code> are ordered), documented in GitHub's <a href="https://docs.github.com/en/code-security/tutorials/fix-reported-vulnerabilities/write-security-advisories">Best practices for writing
repository security advisories</a>,
which is worth five minutes before you fill in this field. It is what version
constraint resolution runs against; "all versions before X" prose in the
description does not replace it. And getting these ranges right matters more than
it used to, because Composer no longer merely <em>reports</em> your advisory. It
<em>enforces</em> it. Read on.</li>
<li><strong>Patched version: the version you are about to release</strong>, the one you want users to
move to. It is what the tooling offers people as the way out, so it belongs in the
form even though you have not tagged it yet at the time you draft the advisory.</li>
</ul>

<h3 id="composer-blocks-the-versions-your-advisory-lists">Composer blocks the versions your advisory lists</h3>

<p>Since <a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html">Composer 2.9</a>,
security advisory enforcement lives in the dependency resolver itself, on by default
for every PHP project. When Composer resolves dependencies (<code>composer update</code>,
<code>require</code>, <code>remove</code>), versions covered by a published advisory are removed from the
candidate pool before the solver runs. As far as the resolver is concerned, they
simply do not exist. <a href="https://blog.packagist.com/composer-2-10-release/">Composer
2.10</a> generalized this into a
unified <em>dependency policy</em> framework that also covers packages flagged as malware
(those are blocked even during <code>composer install</code> from an existing lock file) and
abandoned packages. This machinery replaced the older <code>roave/security-advisories</code>
conflict-package approach. For the full mechanics (pool filtering, <code>config.policy</code>
configuration, ignore rules, escape hatches), see <a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html">The Bouncer in the Dependency
Resolver</a>
and Packagist's <a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">supply chain security
update</a>.</p>

<p>For you as the advisory author, this has three practical consequences:</p>

<ol>
<li><strong>Your advisory directly protects users, even those who never read it.</strong> This is
the strongest argument against fixing silently (<a href="#5.-prepare-the-fix-privately">§5</a>):
an advisory does not just inform, it actively keeps the vulnerable versions out of
<code>vendor/</code> directories across the ecosystem.</li>
<li><strong>Overbroad version ranges cause real breakage.</strong> Once your advisory data reaches
Composer (see step 4 in <a href="#7.-coordinate-the-release-and-publication">§7</a> for what
governs how long that takes), every version it covers becomes uninstallable by
default, everywhere, for everyone. If the ranges
sweep in versions that were never vulnerable, users of those versions face failing
builds, and their bug reports will land in <em>your</em> inbox. This is not hypothetical:
for a PHPUnit advisory in April 2026, GitHub silently rewrote the carefully
specified affected versions (<code>12.5.21</code> and <code>13.1.5</code>) into broad ranges, which made
every older PHPUnit version uninstallable overnight, including all of PHPUnit 11,
which was never affected. The full timeline is documented in <a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html#a-real-world-example">The Bouncer in the
Dependency Resolver</a>.</li>
<li><strong>Know the FriendsOfPHP route, in both directions.</strong> Packagist aggregates
advisories from the GitHub Advisory Database <em>and</em> from
<a href="https://github.com/FriendsOfPHP/security-advisories"><code>FriendsOfPHP/security-advisories</code></a>,
and the FriendsOfPHP data takes precedence. That makes a pull request there both
the fastest way to get your advisory in front of Composer in the first place
(<a href="#7.-coordinate-the-release-and-publication">§7</a>) and the fastest way to fix what
Composer enforces if the published affected-version data turns out to be wrong,
whether through your own mistake or an edit on GitHub's side. For a correction,
send a PR to the <a href="https://github.com/github/advisory-database">GitHub Advisory
Database</a> as well, so that the two
sources do not disagree.</li>
</ol>

<p>The flip side is worth telling your <em>users</em> about, too (in your announcement or your
documentation): with a current Composer, they are protected by default, and
<code>composer audit</code> in CI tells them when an already-locked version has since gained an
advisory.</p>

<p>The rest of the form:</p>

<ul>
<li><strong>Title:</strong> one line, specific, no drama. "SQL injection in report export via
<code>sort</code> parameter" beats "Critical security issue".</li>
<li><strong>Description:</strong> enough for a user to understand <em>whether they are affected</em> and
<em>what to do</em> (upgrade to which version; workaround if one exists). Aim for the
middle ground: too much detail hands attackers a ready-made exploit, too little
starves the tools and the humans reading it. You do not need to include the PoC.</li>
<li><strong>CWE:</strong> pick the closest weakness class. The reporter's suggestion is usually right.</li>
<li><strong>CVSS / severity:</strong> score honestly. If required conditions lower the practical
severity (authentication needed, non-default configuration), reflect that in the
vector rather than in an argument in the description. Keep this in proportion,
though: the score is far less important than the advisory itself. If CVSS makes your
eyes glaze over, an LLM will produce a reasonable first vector for you, and the
Ecosystem Security Team will happily check it; scoring help is a two-minute favor.
Do not let the number hold up the publication.</li>
<li><strong>CVE:</strong> you can request a CVE ID through GitHub from the advisory (GitHub is a CNA
and this is the normal path for Composer packages). Be clear about what it buys you.
A CVE ID is a stable identifier for people outside your immediate ecosystem: Linux
distributions shipping your code, corporate vulnerability management, other CNAs
coordinating a shared issue. What actually protects the average user of your package
is the GHSA, which is what Composer, <code>composer audit</code>, and Dependabot act on. CVE
requests through GitHub currently take weeks to come back, so treat the ID as
something that arrives when it arrives: request it once you have <em>accepted</em> the
report, and never delay the fix, the release, or the advisory while waiting for it.
If a coordinating party such as a CNA has already reserved a CVE for this issue, use
<em>"I have an existing CVE ID"</em> instead of requesting a second one.</li>
<li><strong>Credit:</strong> add the reporter (and anyone who helped) in the credits section. It
costs you nothing and it is a large part of what makes responsible reporting worth
a researcher's while.</li>
</ul>

<h2 id="7.-coordinate-the-release-and-publication">7. Coordinate the release and publication</h2>

<p><em>You are here if: fix ready, advisory drafted, everyone in the private thread agrees.</em></p>

<p>Order matters. On the day you have chosen for your release, follow these steps:</p>

<ol>
<li><strong>Merge</strong> the fix from the private fork.</li>
<li><strong>Tag and release</strong> the fixed version(s), and confirm the release actually shows
up on Packagist before continuing.</li>
<li><strong>Publish the advisory.</strong> From this moment the vulnerability is public, which is
fine, because the fix already is too.</li>
<li><strong>Send a pull request to
<a href="https://github.com/FriendsOfPHP/security-advisories"><code>FriendsOfPHP/security-advisories</code></a>.</strong>
Do not skip this on the grounds that you have already filed a GHSA. Composer does
not look at the advisories published on individual repositories; it goes through
Packagist, which consumes the <em>reviewed</em> GitHub Advisory Database, and GitHub's
review step currently lags behind repository-level publication by days or even
weeks. Until your advisory clears that queue, <code>composer audit</code> stays quiet and the
dependency resolver keeps handing out the vulnerable versions. The FriendsOfPHP
pull request is what closes that gap promptly. And if your project is not hosted
on GitHub at all, this is not an optimization: it is the only route into the
ecosystem's tooling.</li>
<li><strong>Announce</strong> through your normal channels (release notes, Mastodon, Discord, blog),
linking to the advisory. Keep it factual: what the issue is, who is affected, which
version to upgrade to.</li>
</ol>

<p>The gap between step 2 and step 3 should be minutes to hours, not days: a public fix
without an advisory is a window in which attackers can diff your release while your
users have no warning to upgrade.</p>

<p>Two coordination notes:</p>

<ul>
<li>If the report came through a coordinator such as a CNA, agree on the publication
date with them in advance so CVE publication and any wider announcement can happen
in step. The Ecosystem Security Team does not normally ask you to coordinate your
release with us; if a particular case ever calls for it, we will say so explicitly.
We do not want to stand between a report and a fix.</li>
<li>If details leak early (someone tweets, a public issue appears, you spot the bug
being discussed), the embargo is effectively over. Publish what you have as soon as
possible, even if the situation is not as tidy as you wanted.</li>
</ul>

<h2 id="8.-wrap-up">8. Wrap up</h2>

<p><em>You are here if: the advisory is published and the adrenaline is fading.</em></p>

<ul>
<li><strong>Verify the pipeline worked:</strong> the advisory appears in the GitHub Advisory
Database, <code>composer audit</code> flags the vulnerable version in a test project, and
Dependabot alerts fire where expected. Do not expect all of this on publication day:
the advisory on your repository has to clear GitHub's review queue before Composer
sees it, which is exactly what the FriendsOfPHP pull request
(<a href="#7.-coordinate-the-release-and-publication">§7</a>) is there to short-circuit. If it
still has not arrived after a few days, check the ecosystem and package-name fields
first (<a href="#6.-write-the-github-security-advisory">§6</a>); those are the usual suspects
when matching silently fails.</li>
<li><strong>Verify the blocking is not too eager:</strong> in a scratch project, check that the
<em>fixed</em> version and unaffected release series still install and update cleanly.
Compare the affected-version ranges shown in the <a href="https://github.com/advisories">GitHub Advisory
Database</a> against what you wrote (they have been
known to change during publication), and keep an eye on your issue tracker for
"cannot install version X" reports in the first days after publishing. The
correction path is described in <a href="#composer-blocks-the-versions-your-advisory-lists">§6</a>.</li>
<li><strong>Thank the reporter</strong> once more, in public if they are comfortable with that.</li>
<li><strong>Check your other supported branches</strong> one final time; it is easy to patch the
current major and forget the LTS branch.</li>
<li><strong>Hold a fifteen-minute retrospective with yourself:</strong> How did this bug get in?
Would a static analyzer, a stricter type, or a test convention have caught it? The
sweep for siblings of this bug should already be behind you at this point
(<a href="#5.-prepare-the-fix-privately">§5</a>); what you are looking for here is the one
structural change that stops the whole class from recurring. One such improvement
per incident compounds quickly.</li>
</ul>

<h2 id="9.-improving-your-security-posture-for-the-long-term">9. Improving your security posture for the long term</h2>

<p><em>You are here if: the storm has passed and you want the next one to be smaller. This
section is also the right starting point if no report has arrived yet and you simply
want to prepare.</em></p>

<p>You do not need to do all of this in one weekend. The list is roughly ordered by
value-for-effort; even the first three items put you ahead of most projects.</p>

<p><strong>Make it easy to report to you</strong></p>

<ol>
<li><strong>Enable GitHub Private Vulnerability Reporting</strong> (repository → Settings →
Advanced Security → Private vulnerability reporting → Enable). Without it,
reporters must choose between emailing you cold and opening a public issue, and
some will choose the public issue.</li>
<li><strong>Add a <code>SECURITY.md</code></strong> stating how to report (ideally: "use private vulnerability
reporting on this repository"), which versions you support with security fixes,
and roughly what response time to expect. Three honest sentences beat a page of
boilerplate.</li>
<li><strong>Watch your own security tab.</strong> Two different things land there and both are worth
a notification: <em>security advisories</em>, which is where a report about <strong>your</strong> code
arrives, and <em>Dependabot alerts</em>, which tell you that a dependency <strong>you</strong> use has
a published vulnerability. Make sure you are notified about both: watch the
repository with security alerts enabled, and check the notification settings on
your GitHub account, so that neither sits unseen for months.</li>
</ol>

<p><strong>Protect your accounts and releases</strong></p>

<ol start="4">
<li><strong>Strong 2FA/MFA everywhere that can publish:</strong> GitHub, Packagist, your email
account (which can reset the other two). Prefer passkeys or hardware keys over SMS.
Audit who else has publish rights and remove stale access. On Packagist this is
becoming a visible property of your packages, not just private hygiene:
<a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">Packagist.org will surface maintainer MFA status publicly</a>
in its transparency log and on profiles, with mandatory MFA as the stated
long-term direction. Most of the recent supply-chain attacks in the PHP ecosystem
began with a taken-over maintainer account.</li>
<li><strong>Protect your release path:</strong> branch protection on <code>main</code>, tag protection for
release tags, and no long-lived personal access tokens with broad scopes lying
around in CI secrets or on disk.</li>
<li><strong>Never re-tag a released version.</strong> If a release has a problem, ship a new
version; do not overwrite the tag. Mirrors, scanners, and lock files already hold
copies of the original, and two variants of "the same" version circulating is a
mess your users cannot untangle. Packagist.org now
<a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">enforces this</a>:
stable versions are immutable, and upstream re-tagging is detected and rejected,
not least because silently rewritten tags were the core move in recent attacks on
compromised packages.</li>
</ol>

<p><strong>Reduce your attack surface</strong></p>

<ol start="7">
<li><strong>Delete what does not need to exist.</strong> Every branch in your repository is a door:
a target for pull requests that carry along modified workflow files, build
scripts, or configuration the pipeline will happily execute. This class of attack
is known as <a href="https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-04-Poisoned-Pipeline-Execution">Poisoned Pipeline Execution</a>
(OWASP CICD-SEC-4). A branch that does not exist cannot receive a poisoned pull
request, and no door protects better than the one that was never built.
Review your branches and remove stale experiments, leftovers from old sprints,
and "we might still need this" remnants. The same goes for unused workflows,
third-party actions, and permissions nobody questions anymore. See <a href="https://phpunit.expert/articles/the-attack-surface-begins-in-the-repository.html">The attack
surface begins in the
repository</a>
for the full argument, including real-world PPE incidents from SolarWinds to
PyTorch.</li>
</ol>

<p><strong>Harden your automation</strong></p>

<ol start="8">
<li><p><strong>Treat your workflow files as security-relevant code.</strong> They run with
credentials, network access, and write permission to your repository. The five
weakness classes that show up almost everywhere, PHPUnit's own workflows included
(52 findings before hardening, zero after):</p>

<ul>
<li><strong>Template injection:</strong> never interpolate
<code>${{ ... }}</code> expressions (branch names, PR titles,
and other attacker-controllable values) directly into shell scripts; pass them
through <code>env:</code> variables instead. This is the GitHub Actions equivalent of SQL
injection.</li>
<li><strong>Credential persistence:</strong> set <code>persist-credentials: false</code> on
<code>actions/checkout</code>, so the workflow token does not sit in <code>.git/config</code> for
every later step (or exfiltrated artifact) to read.</li>
<li><strong>Unpinned actions:</strong> pin every action to a full commit SHA with the tag as a
comment. A floating tag like <code>@v4</code> can be repointed at malicious code by anyone
who compromises the action, which is exactly how the <code>tj-actions/changed-files</code>
attack reached 23,000 repositories. Let Renovate or Dependabot keep the SHAs
current.</li>
<li><strong>Overly broad permissions:</strong> set <code>permissions: {}</code> at the workflow level and
grant minimal scopes per job, with a comment explaining each grant. Set the
baseline for the whole repository, too: under Settings → Actions → General →
Workflow permissions, choose read-only, so that a workflow which forgets to
declare <code>permissions:</code> does not start out with write access to your repository.</li>
<li><strong>Unnecessary third-party actions:</strong> if the runner's built-in tooling (e.g. the
<code>gh</code> CLI) can do the job, drop the wrapper action. Every action is more code
running next to your secrets, and one more upstream that can be compromised to
reach you.</li>
</ul>

<p>You do not need to memorize this list: run <a href="https://docs.zizmor.sh/">zizmor</a>
against <code>.github/workflows</code>, fix what it finds, and add it to CI so regressions
are caught immediately. A full walkthrough, taking each weakness in turn with an
example exploit and its fix, is in <a href="https://phpunit.expert/articles/hardening-github-actions-workflows.html">Hardening GitHub Actions
workflows</a>.
Be especially careful with the <code>pull_request_target</code> and <code>workflow_run</code> triggers,
which run with the base repository's permissions against fork contributions.</p></li>
<li><strong>Run <code>composer audit</code> in CI</strong> so you learn about vulnerable dependencies from
your pipeline rather than from your users, and know that with a current Composer,
your users' resolvers block advisory-affected and malware-flagged versions of
<em>your</em> dependencies too (<a href="#composer-blocks-the-versions-your-advisory-lists">§6</a>).
Add a static analyzer (PHPStan or Psalm) at a level that at least catches the
classics: unvalidated input flowing into queries, file paths, or <code>unserialize()</code>.</li>
</ol>

<p><strong>Build habits</strong></p>

<ol start="10">
<li><strong>Keep an isolated reproduction environment ready</strong> (<a href="#4.-handle-proof-of-concept-code-safely">§4</a>),
so that "spin up the VM" is a two-minute routine rather than a reason to take the
dangerous shortcut.</li>
<li><strong>Treat security reports as a normal category of work,</strong> with the small process
from this guide, rather than as emergencies. The calmer the routine, the better
every individual case goes.</li>
<li><strong>Know who to call.</strong> Which brings us to the final section.</li>
</ol>

<h2 id="10.-getting-help">10. Getting help</h2>

<p>You never have to work through any of this alone. The <strong>PHP Foundation Ecosystem
Security Team</strong> exists precisely to support maintainers like you: with triage,
reproduction of findings in isolated environments, impact analysis, deduplication of
report floods, fix validation, severity scoring, and coordinated disclosure. Asking
early is always better than guessing; there is no question too basic.</p>

<ul>
<li><strong>Email:</strong> <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#x6f;&#58;&#x76;&#111;&#x6c;&#x6b;&#101;&#x72;&#64;&#x74;&#x68;&#101;&#x70;&#104;&#x70;&#x2e;&#102;&#x6f;&#117;&#x6e;&#x64;&#97;&#x74;&#105;&#x6f;&#x6e;">volker@thephp.foundation</a>
(Volker Dusch, Ecosystem AI Security Engineer in Residence at the PHP Foundation)</li>
<li><strong>Discord:</strong> <code>#ecosystem-security</code> on the phpc community server
(<a href="https://discord.com/invite/RYajXKxuuK">invite</a>), where Volker is <code>@edorian</code></li>
<li><strong>Background on the team:</strong>
<a href="https://thephp.foundation/blog/2026/05/18/announcing-ecosystem-security-team/">Announcing the Ecosystem Security Team</a> ·
<a href="https://thephp.foundation/blog/2026/06/23/one-month-of-ecosystem-security-engineering/">One Month of Ecosystem Security Engineering</a></li>
</ul>

<h3 id="further-reading">Further reading</h3>

<ul>
<li><a href="https://alpha-omega-security.github.io/maintainers-security-advisory-guide/">The Maintainer's Guide to GitHub Security Advisories</a>
(Alpha-Omega): the in-depth, ecosystem-agnostic companion to this document, with a
cheatsheet, FAQ, and workarounds for GitHub platform limitations</li>
<li><a href="https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability">GitHub Docs: Privately reporting a security vulnerability</a></li>
<li><a href="https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/fix-reported-vulnerabilities/create-repository-advisory">GitHub Docs: Creating a repository security advisory</a>:
the click-by-click walkthrough of the advisory form, including the CVSS
calculator and credit types</li>
<li><a href="https://docs.github.com/en/code-security/tutorials/fix-reported-vulnerabilities/write-security-advisories">GitHub Docs: Best practices for writing repository security advisories</a>:
the reference for ecosystem, package name, and affected-version syntax,
including operators and prerelease-suffix pitfalls</li>
<li><a href="https://getcomposer.org/doc/03-cli.md#audit">Composer: <code>composer audit</code></a> and the
<a href="https://getcomposer.org/doc/06-config.md#policy">dependency policy configuration</a></li>
<li><a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html">The Bouncer in the Dependency Resolver</a>
(Sebastian Bergmann): how Composer's advisory and malware blocking works under the
hood, including a real-world case of an advisory blocking too much</li>
<li><a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">An update on Composer &amp; Packagist supply chain security</a>
and the <a href="https://blog.packagist.com/composer-2-10-release/">Composer 2.10 release announcement</a>
(Packagist): the current state and roadmap covering dependency policies, version
immutability, the transparency log, and MFA</li>
<li><a href="https://phpunit.expert/articles/the-attack-surface-begins-in-the-repository.html">The attack surface begins in the repository</a>
and <a href="https://phpunit.expert/articles/hardening-github-actions-workflows.html">Hardening GitHub Actions workflows</a>
(Sebastian Bergmann): Poisoned Pipeline Execution and the concrete workflow
weaknesses behind <a href="#9.-improving-your-security-posture-for-the-long-term">§9</a></li>
<li><a href="https://cwe.mitre.org/">CWE (Common Weakness Enumeration)</a> and
<a href="https://www.first.org/cvss/">CVSS (Common Vulnerability Scoring System)</a></li>
<li><a href="https://cna.erlef.org/maintainer-process">EEF CNA Maintainer Process</a>: the Erlang
ecosystem's equivalent process, a model for this guide</li>
</ul>

<hr />

<p><em>If anything here was unclear, took too long to figure out, or turned out to be wrong
in practice, please tell us; that feedback directly improves the experience of the
next maintainer. You can reach us at the addresses in <a href="#10.-getting-help">§10</a>.</em></p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[How to Contribute to PHP]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/17/how-to-contribute-to-php/"/>
            <updated>2026-08-17T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/17/how-to-contribute-to-php/</id>
            <content type="html"><![CDATA[<p>PHP has powered a huge portion of the web for a <em>long</em> time now. It's launched untold numbers of careers and businesses, and many developers attribute their entire careers to the language. But when we find ourselves wanting to give back, it's not always clear how; sure, PHP is open source, but where do we contribute? How?</p>

<p>I've run into that wall before. My immediate issue was that I didn't write C, followed pretty immediately by how overwhelming it felt to learn the entire RFC-and-mailing-list-driven contribution process.</p>

<p>Thankfully, it turns out there are many ways to contribute to PHP, and writing C or proposing an RFC are just two of many options. I'm glad to share I've found <em>many</em> other ways to give back, and I'm confident you can as well.</p>

<p>When we talk about "contributing to PHP," there are really two ways: <strong>contributing directly to the PHP project</strong>, and <strong>contributing to the broader PHP ecosystem</strong>. Both are needed and both are valid, so we'll walk through both in this guide. Wherever any potential path gets technical, we'll point you to the canonical instructions rather than duplicate them here.</p>

<h2 id="php%2C-the-php-foundation%2C-and-the-ecosystem">PHP, the PHP Foundation, and the ecosystem</h2>

<p>Before we go any further, I want to clear up the difference between a few different concepts with "PHP" in their names which we'll be referring to throughout this post:</p>

<ul>
<li><strong>The PHP project</strong> — a language, and the open-source project around it: the implementation, tests, documentation, and releases, and the technical decision-making that guides it all.</li>
<li><strong>The PHP ecosystem</strong> — everything else built around PHP: packages, frameworks, tooling, conferences, education, communities, and publications.</li>
<li><strong>The PHP Foundation</strong> — an organization that supports the long-term health of PHP, including funding programmers and coordinating and supporting community initiatives.</li>
</ul>

<p>And to clear up an important governance distinction, since this is posted on the PHP Foundation's blog: the Foundation does not own PHP, it doesn't govern its development, and it doesn't dictate RFCs. PHP is an independent open-source project with its own contributors and its own decision-making process, and we like it that way! The Foundation exists to support that work.</p>

<h1 id="part-one%3A-contributing-directly-to-php">Part One: Contributing directly to PHP</h1>

<h2 id="core-contribution-is-broader-than-you-might-think">Core contribution is broader than you might think</h2>

<p>When most people picture the idea of "contributing to PHP core," the first thing that comes to mind is proposing a new language feature. But that's actually the deepest end of that pool, and it's only a small part of the work it takes to run a language.</p>

<p>There are so many other ways people can contribute to the project, including testing releases, reporting bugs, reproducing bugs others have reported, writing tests, improving documentation, reviewing changes, fixing issues, participating in internals discussion, and, yes, RFCs.</p>

<p>Let's walk through these, roughly from the lowest barrier to entry to the highest.</p>

<h2 id="1.-test-prereleases">1. Test prereleases</h2>

<p>Every new major, minor, or patch PHP version ships with a prerelease. Patch versions just get an RC (release candidate), and major/minor versions receive a series of prereleases — alphas, betas, and release candidates — before the final release. These exist so the community can catch problems while they're still cheap to fix. The more real-world code that runs against a prerelease, the more confident everyone can be that the final release won't break things.</p>

<p>If you maintain a package, run its test suite against the next prerelease. If you run a large real-world application, run its tests on the prerelease, or point a local or staging environment at it. When something breaks, you've found either a genuine regression worth reporting or a change you'll need to prepare for, both of which are valuable.</p>

<p>If you want to go a step further, test against PHP's master branch continuously rather than only at prerelease time; projects like PHPUnit and Xdebug already do this, so they catch regressions the moment they land. One caveat: don't gate your CI on it. Let a master-branch build fail without failing your whole suite, since you're deliberately testing against unreleased, in-progress code. PHPUnit's Sebastian Bergmann has written up <a href="https://phpunit.expert/articles/how-php-and-its-ecosystem-test-each-other.html">how PHP and its ecosystem test each other this way</a>.</p>

<p>PHP announces each alpha, beta, and release candidate on <a href="https://www.php.net/">php.net</a>, together with the source downloads and release schedule for that version. You can use your preferred version management or container tooling to install the prerelease, or <a href="https://github.com/php/php-src#building-php-source-code">build it yourself locally</a>, and then run your application's or package's test suite against it. If you find something that looks like a regression in PHP itself, reduce it to the smallest reproduction you can and report it to the <a href="https://github.com/php/php-src/issues"><code>php-src</code> issue tracker</a>.</p>

<p><strong>First step:</strong> Grab the current prerelease and run something you already maintain against it.</p>

<h2 id="2.-report-and-reproduce-bugs">2. Report and reproduce bugs</h2>

<p>A good bug report is itself a contribution, and so is confirming or reproducing someone else's.</p>

<p>Before you file anything, search the <a href="https://github.com/php/php-src/issues">existing <code>php-src</code> issues in GitHub</a>; this problem may already be known. If it isn't, the most valuable thing you can do is reduce it to a <strong>minimal reproduction</strong>: the smallest snippet of code that will reliably trigger the undesirable behavior, along with your PHP version, platform, and any other relevant environment details. The <a href="https://github.com/php/php-src/blob/master/CONTRIBUTING.md"><code>php-src</code> contribution guide</a> has additional guidance on filing and working with issues.</p>

<p>And to clear up a common misconception, it's still valuable to report a bug even if you don't know how to fix it.</p>

<p><strong>First step:</strong> Search the issues, then either file your own issue or try to reproduce someone else's unconfirmed report.</p>

<h2 id="3.-improve-documentation">3. Improve documentation</h2>

<p>PHP's documentation is vast, and like all large (and long-running) documentation projects, it still contains plenty of unclear passages, missing examples, and pages describing behavior that has changed since its writing. Improving any of these helps every developer who lands on that page after you.</p>

<p>For small changes, you don't even need to set up the documentation project locally: the PHP manual's <a href="https://doc.php.net/guide/contributing.md">contribution guide</a> explains how to propose an edit directly through GitHub. If you're interested in translation work, there's a separate <a href="https://doc.php.net/guide/translating.md">translation guide</a>.</p>

<p>Here are a few concrete examples: clarifying a confusing sentence, adding a clear example to a function that lacks (and needs) one, documenting an edge case you had to discover the hard way, correcting behavior that's drifted over versions, or improving a translation into your language. And "improving the docs" isn't only about what's written: the documentation project also has tooling (CI, linting, etc.) that welcomes contributions.</p>

<p><strong>First step:</strong> The next time a docs page confuses you, propose a fix instead of just closing the tab in frustration.</p>

<h2 id="4.-write-tests">4. Write tests</h2>

<p>PHP has its own test format, called <strong>PHPT</strong>: plain-text files that describe a bit of PHP to run and the output it should produce. They're how the language guards against regressions, and they're a natural bridge between everyday PHP development and working in <code>php-src</code>.</p>

<p>A PHPT test is deliberately simple. At its core it's three sections: the description, a section describing the code to run, and a section describing the expected output:</p>

<pre><code>--TEST--
strlen() returns the number of bytes in a string
--FILE--
&lt;?php
var_dump(strlen("hello"));
?&gt;
--EXPECT--
int(5)
</code></pre>

<p>The <a href="https://php.github.io/php-src/miscellaneous/writing-tests.html"><code>php-src</code> testing guide</a> walks through the full PHPT format and how to write useful tests; once you're working from a local PHP build, the <a href="https://php.github.io/php-src/miscellaneous/running-tests.html">test-running guide</a> explains how to execute them.</p>

<p>Similar to how it's valuable to report an issue even if you don't know how to fix it, it's valuable to write a test for a bug even if you don't know how to fix it. If you can write PHPT that reliably fails on a known bug, you've pinned the problem down precisely and made the process of writing and validating a fix that much easier.</p>

<p><strong>First step:</strong> Turn a bug you've reproduced into a failing PHPT.</p>

<h2 id="5.-fix-or-review-issues-in-php-src">5. Fix or review issues in php-src</h2>

<p>This is the point where contribution moves into the implementation itself, and where knowing some C starts to matter. It's a bigger step, but still very clear. Here's generally how it works:</p>

<ol>
<li>Get PHP building locally.</li>
<li>Find a scoped, well-defined existing problem to work on.</li>
<li>Comprehend the problem, and reproduce it for yourself locally.</li>
<li>Add or update tests that capture the correct behavior.</li>
<li>Implement the fix.</li>
<li>Open a pull request.</li>
<li>Work through any review with the maintainers.</li>
</ol>

<p>I know "just get PHP building locally" is doing a lot of work in that first step. The <a href="https://php.github.io/php-src/"><code>php-src</code> developer documentation</a> and <a href="https://github.com/php/php-src/blob/master/CONTRIBUTING.md">CONTRIBUTING.md</a> are the best places to start with setting up a development environment and understanding the contribution workflow.</p>

<p>There's also the other half of this process: <strong>reviewing and testing someone else's pull request.</strong> Pull down an open PR, build it, check that it does what it claims, and then leave your findings on the PR. And this may actually be simpler than opening your first PR from scratch.</p>

<p><strong>First step:</strong> Get PHP building locally, then browse the <a href="https://github.com/php/php-src/issues"><code>php-src</code> issues</a> for a narrowly scoped, already-verified bug in an area you understand.</p>

<h2 id="6.-participate-in-internals">6. Participate in internals</h2>

<p>Technical discussion about the direction of PHP happens openly on the <a href="https://www.php.net/mailing-lists.php">internals mailing list</a>, PHP's long-running development mailing list. You don't have to write C to follow along, and you don't have to be an established contributor to add value.</p>

<p>In fact, many people participating in internals conversations aren't traditional core developers. That goes both ways: it means you, even as a newcomer, are as welcome to participate as anyone, but it also means not every reply you might receive should carry the same weight. That means a strong objection from one participant can't be seen as the same as a decision; weigh feedback by its reasoning and don't be discouraged by a single dissenting voice.</p>

<p>The internals mailing list also does have a <a href="https://github.com/php/php-src/blob/master/docs/mailinglist-rules.md">written guide</a>, which lays out how to participate. I'd recommend reading the whole thing before you post.</p>

<p><strong>First step:</strong> Subscribe to the <a href="https://www.php.net/mailing-lists.php">internals mailing list</a>, or browse past and current discussions on <a href="https://externals.io/">externals.io</a>, and just listen for a while.</p>

<h2 id="7.-rfcs%3A-changing-the-language-itself">7. RFCs: changing the language itself</h2>

<p>RFCs (Requests for Comments) are the processes by which significant changes to the language are formally proposed and decided. They're the part of contributing to core that gets the most attention, so it's worth being clear about what they are and aren't.</p>

<p>First: <strong>not every code change requires an RFC.</strong> Plenty of bug fixes land through ordinary pull requests. RFCs exist for new features and other changes significant enough to need formal decision-making through the RFC process.</p>

<p>Second: <strong>an RFC is much more than an idea.</strong> A proposal that will be taken seriously requires research into prior art, careful design, analysis of backward-compatibility impact, a credible implementation plan (and often an implementation), a period of discussion, revision in response to feedback, a formal vote, and technical review throughout. The idea is the easy part; everything around it is the work.</p>

<p>Two things newcomers often miss:</p>

<ul>
<li><strong>You can contribute to an RFC without being its author.</strong> Testing a proposed implementation, poking holes in the design, surfacing a compatibility problem, or providing real-world use cases all move a proposal forward.</li>
<li><strong>An accepted proposal still has to become good software.</strong> A "yes" vote is the beginning of the implementation's real life, not the end.</li>
</ul>

<p>If you're not ready to author an RFC yourself, a great way to learn the process is to follow one that's currently under discussion. Read the proposal and its linked internals discussion, try the implementation if one is available, and look for places where your own experience can add useful evidence: compatibility concerns, interactions with existing features, real-world use cases, or behavior the proposal may not have considered. You don't need voting privileges to participate in the discussion or test the implementation.</p>

<p><strong>First step:</strong> Browse the <a href="https://wiki.php.net/rfc">current RFC list</a>, choose one that's under discussion, and follow it end to end. If you're considering proposing your own change, start with the official <a href="https://wiki.php.net/rfc/howto">How to create an RFC</a> guide.</p>

<h1 id="part-two%3A-contributing-to-php%27s-ecosystem">Part Two: Contributing to PHP's ecosystem</h1>

<p>The PHP project is only part of the story. Most developers spend more of their time in the ecosystem around it — the packages, frameworks, tools, communities, and education that make PHP an ecosystem, not just a language. Contributing here is not a consolation prize for people who can't work on core; for most of the community, it's where their highest-value contributions actually live.</p>

<h2 id="1.-help-existing-open-source-projects">1. Help existing open-source projects</h2>

<p>The packages, frameworks, and tools you already use are maintained by real people; often very few of them, and often unpaid. They almost all need help: issue triage, pull-request review, documentation, testing against upcoming PHP versions, and general maintenance. Abandoned-but-widely-used projects sometimes need someone to step in and adopt them entirely — and that includes PHP's own bundled extensions, many of which have few or no active maintainers, so a domain you know well may be a genuine gap you can fill.</p>

<p>It's tempting to think the way to contribute is to build something new. But <em>creating another package is not necessarily more valuable than maintaining one thousands of people already depend on.</em> In fact, it's often worse. Strengthening what exists is often the more valuable choice.</p>

<p><strong>First step:</strong> Pick a dependency you rely on and spend an hour in its issue tracker.</p>

<h2 id="2.-teach-and-help-developers">2. Teach and help developers</h2>

<p>Teaching is infrastructure. An ecosystem is only as healthy as its ability to bring new people in and help existing developers level up, and that ability runs almost entirely on people who take the time to explain things.</p>

<p>That includes writing tutorials and documentation, producing upgrade guides, giving talks, mentoring, answering questions in forums and chat, and helping newcomers land their very first contribution. None of this requires permission, and all of it builds on the rest.</p>

<p><strong>First step:</strong> Write up the last thing you had to figure out the hard way.</p>

<h2 id="3.-strengthen-php-communities">3. Strengthen PHP communities</h2>

<p>The PHP community exists because people build and sustain the spaces it lives in: local meetups, conferences, online communities.</p>

<p>You don't need to start a conference. Consider volunteering to assist a local meetup, or simply working to make a newcomer feel welcome in one. Or, if you haven't attended one yet, just show up!</p>

<p><strong>First step:</strong> Show up to a local or online PHP community and meet people; if you're already there and want to do more, ask how you can help.</p>

<h2 id="4.-help-php-show-up-outside-the-php-bubble">4. Help PHP show up outside the PHP bubble</h2>

<p>Plenty of the world's developers have formed their impression of PHP from someone else's read on the language from the '90s. The best way to update these impressions is to make sure PHP is represented accurately where non-PHP developers actually are.</p>

<p>That looks like giving PHP talks at general software conferences, contributing PHP SDKs or examples to language-neutral projects, adding modern PHP examples to developer education, publishing case studies from real applications, and improving PHP support in general-purpose developer tooling.</p>

<p>That outward-facing work is exactly what the Foundation's Ambassador Program is built to coordinate.</p>

<h1 id="part-three%3A-php-foundation-opportunities">Part Three: PHP Foundation opportunities</h1>

<p>In addition to everything above, the Foundation explicitly offers some structured ways to plug in. These are intentionally building space for contributions outside of code, like marketing, conference speaking, research, and more.</p>

<p>In 2026, the Foundation is launching six <strong>Special Interest Groups</strong>, covering the following areas: ecosystem security, <a href="https://thephp.foundation/blog/2026/06/19/the-php-ambassador-program-is-open/">PHP advocacy</a>, <a href="https://thephp.foundation/blog/2026/08/03/kicking-off-the-php-onboarding-initiative/">onboarding</a>, cryptography, community events, and accessibility and inclusion. The Foundation also periodically looks for community participation in surveys, consultations, and other initiatives.</p>

<p>And for people or organizations that don't have contributor time to spare, <a href="https://thephp.foundation/sponsor/"><strong>financial support</strong> to the Foundation</a> is another way to enable this work — funding the contributors and initiatives that keep PHP moving.</p>

<h2 id="when-you-get-stuck-or-hear-nothing-back">When you get stuck (or hear nothing back)</h2>

<p>At some point you'll get stuck in one of these processes, or you'll open a pull request and hear nothing back for a while. Both are normal, and neither means you necessarily did anything wrong. Contribution runs largely based on the work of volunteers, and volunteer attention is limited.</p>

<p>When you need help, there are a few good places to turn:</p>

<ul>
<li><strong>General questions and getting unstuck:</strong> The <a href="https://phpc.chat/">PHP Community Discord</a> is the most active real-time gathering spot, with channels ranging from beginner questions to core development. There's even a <code>#php-src-help</code> channel specifically for this sort of work. For longer-form questions, the <a href="https://www.reddit.com/r/PHP/">r/PHP subreddit</a> and the <a href="https://stackoverflow.com/questions/tagged/php"><code>php</code> tag on Stack Overflow</a> are both well-trafficked.</li>
<li><strong>Core and internals questions:</strong> For questions specific to working on <code>php-src</code>, that same Discord has a <code>#php-internals</code> channel where core developers hang out, and the <a href="https://www.php.net/mailing-lists.php">internals mailing list</a> is the canonical venue for development discussion.</li>
<li><strong>A <code>php-src</code> PR or RFC that's gone quiet:</strong> The internals mailing list is the right place to politely follow up. A short, respectful message linking your PR or proposal is a normal and accepted way to ask for eyes on stalled work.</li>
</ul>

<h2 id="pick-one-thing">Pick one thing</h2>

<p>You don't have to try everything in this article. Pick one that fits your current level of experience and available time, and run with it.</p>

<ul>
<li><strong>If you have 30 minutes:</strong> fix a confusing docs page, confirm an open issue, or answer someone's question.</li>
<li><strong>If you have an afternoon:</strong> test a prerelease, build a minimal reproducible example, or investigate a bug.</li>
<li><strong>If you want a project:</strong> write a test, take on a scoped issue, or help maintain a package you depend on.</li>
<li><strong>If you want an ongoing role:</strong> review contributions, maintain software, organize community, or get involved in internals or Foundation work.</li>
</ul>

<p>Whatever you pick, hold onto this:</p>

<p><strong>If you write PHP, you are qualified to contribute to PHP.</strong> Don't let anyone tell you otherwise.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[PHP Ambassadors: Six Weeks In]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/13/php-ambassadors-six-weeks-in/"/>
            <updated>2026-08-13T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/13/php-ambassadors-six-weeks-in/</id>
            <content type="html"><![CDATA[<p>When we <a href="https://thephp.foundation/blog/2026/06/19/the-php-ambassador-program-is-open/">launched the PHP Ambassador Program</a> on June 19, 2026, we honestly didn’t know what to expect. We knew the need for something like this was definitely there, and it <em>seemed</em> like something the community would be interested in being a part of. But as they say, “you never know how a thing is going to go, until it goes.”  I mentioned in my <a href="https://thephp.foundation/blog/2026/06/11/integrating-community-feedback-into-foundation-strategy-part2/">strategy document</a> that I was hoping to enlist 10 people to attend a regular cadence of meetings. (Honestly, 10 people seemed like a reasonable number.)</p>

<p>Not only did you all surpass that number by leaps and bounds, you continue to show up and join the group. <em>We now have 150 people who have expressed interest in the Program</em>. I couldn’t be more excited about your enthusiasm!</p>

<h2 id="what-we-learned">What we learned</h2>

<p>Some things we’ve learned about this group:</p>

<ul>
<li><strong>Maintain flexible infrastructure choices:</strong> When starting a new community, it's important to remember that it’s ok to try different options for infrastructure. Every community takes on a life of its own, and for this group, GitHub Discussions did not seem to take hold as a place where the community wanted to interact. As well, Google Meet did not provide us with the options for meeting management that we wanted. And third, inviting folks individually to meetings became unwieldy and got me flagged as a spammer. So instead of using GitHub, Google Meet, and Google invites, we are using Discord, Zoom, and a Google calendar to manage this community's interactions and these meetings.</li>
<li><strong>Divide and conquer:</strong> We had enough interest to break the larger group into smaller, more focused groups:

<ul>
<li>Research: focused on locating and vetting sources of information and truth that the community can use in their articles and presentations</li>
<li>Marketing: focused on the messaging of PHP (including the php.net website)</li>
<li>Speakers: focused on providing structure and resources for people who want to give talks outside the PHP ecosystem</li>
</ul></li>
<li><strong>Give opportunities for overlap:</strong> As our topics of discussion became more focused, many people wanted to be in more than one group at a time. Also, a 30 minute breakout once a month is not enough to make real progress.  For those reasons, we have afforded each group their own meeting space, while maintaining the monthly meeting that includes everyone. Allowing people to participate in more than one group at a time means there will be more opportunities for cross-pollination and coordination among the three subgroups.</li>
</ul>

<h2 id="group-progress">Group Progress</h2>

<p>Ideas are great, but what about actions? We have a goal in each group to build tangible assets and to keep momentum going. Launching is hard, but maintaining engagement and providing real outcomes is harder. So let's talk about what each of these groups is currently working on.</p>

<h3 id="research">Research</h3>

<p>As the smallest of the three groups, we tasked ourselves with identifying and listing the current available resources that are out there around PHP usage and other data points that might be of interest to our community. We felt that it was important to have a lay of the land as a starting point. We are still working on putting this into a format that we can share in the <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-research">Research portion of the SIG-Ambassador Repo</a>, but we have some notes started. If you know of a source of data that should be included, please share with us by <a href="https://github.com/ThePHPF/SIG-ambassadors/issues">opening an issue in the repo</a>.</p>

<p><strong>Group Info:</strong></p>

<ul>
<li>Discord channel: <a href="https://discord.com/channels/356354025865740288/1530212583833997392">#php-amb-research</a></li>
<li>GitHub repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-research">Research subgroup</a></li>
<li>Next meeting: <strong>Friday, August 28, 2026 at 13:00 UTC</strong></li>
</ul>

<h3 id="marketing">Marketing</h3>

<p>There is an <a href="https://github.com/php/web-php/pull/1962">active draft PR</a> that proposes some initial structural updates to the php.net website. The original PR was created largely from the work of Mark Randall, and it has gone through several collaborative iterations. The php.net website was one of the things most mentioned to me in the <a href="https://thephp.foundation/blog/2026/04/16/integrating-community-feedback-into-foundation-strategy-part1/">Listening Tour</a> as a place that could use some help, so it’s great to see this next iteration being created by the community. I would venture to say this is the first in many iterations to come! Thanks to <a href="https://www.linkedin.com/in/mattstauffer/">Matt Stauffer</a> for shepherding this group and keeping progress moving forward.</p>

<p><strong>Group Info:</strong></p>

<ul>
<li>Discord channel: <a href="https://discord.com/channels/356354025865740288/1530212454309826571">#php-amb-marketing</a></li>
<li>GitHub repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-marketing">Marketing subgroup</a></li>
<li>Next meeting: <strong>Friday, August 14, 2026 at 14:00 UTC</strong></li>
</ul>

<h3 id="speakers">Speakers</h3>

<p><a href="https://www.linkedin.com/in/secondej/">James Seconde</a> from Vonage has done an amazing job shepherding this third and final group: the speakers. He has started a PR that offers <a href="https://github.com/ThePHPF/SIG-ambassadors/pull/24">guidelines for a more structured, Foundation-backed Speaker Program</a>. The community has chimed in, but we are still open to receiving feedback on how a program like this might work. This group has also started compiling a <a href="https://docs.google.com/spreadsheets/d/1TCy25FqB_c2n1UhwtGN4AdL_plMPHQceNi6UpOSjBok/edit">spreadsheet of events</a> outside our PHP bubble as a resource for PHP Ambassador speakers (or anyone else in the community). We would appreciate more eyes on this and the addition of more information. If you have thoughts on either of these things, we highly encourage you to join this group!</p>

<p><strong>Group Info:</strong></p>

<ul>
<li>Discord channel: <a href="https://discord.com/channels/356354025865740288/1530212493019058257">#php-amb-speakers</a></li>
<li>GitHub repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-speakers">Speakers subgroup</a></li>
<li>Next meeting: <strong>Thursday, August 27, 2026 at 13:00 UTC</strong></li>
</ul>

<h2 id="join-us%21">Join us!</h2>

<p>If shaping the messaging around PHP and improving the perception of the language outside our bubbles is important to you, we would love to include you in this group!</p>

<p>Even if you aren’t sure where you fit in, you can participate in the larger effort:</p>

<ul>
<li>Discord: <a href="https://discord.com/channels/356354025865740288/1521534247813255229">#php-ambassadors</a></li>
<li>Repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main">SIG-Ambassadors</a></li>
<li>Calendar of meetings: <a href="https://calendar.google.com/calendar/u/3?cid=Y19lMzY3ZGQyMzRiNTkwZGExY2M1NjM3ZTEyZmE2ODJlYjA0YzZkOWU4N2E5OWY1ZDY2YzMxNjI5YmIxYTE4MDNkQGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20">Subscribe here</a></li>
<li>Next meeting: <strong>Friday, August 14, 2026 at 13:00 UTC</strong></li>
</ul>

<p>To be added to the mailing list where you will be kept up-to-date on all the PHP Ambassador news, register your interest using <a href="https://forms.gle/cAFDZ1gC22ajxx6VA">this form</a>. (Of course you can unsubscribe at any time, and we will still love you. We promise.)</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Anne McCarthy Joins The PHP Foundation Board]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/04/anne-mccarthy-joins-the-board/"/>
            <updated>2026-08-04T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/04/anne-mccarthy-joins-the-board/</id>
            <content type="html"><![CDATA[<p><img src="/assets/post-images/2026/anne-mccarthy/anne-mccarthy.jpg" width="300" alt="photo of anne mccarthy giving a presentation" class="mb-4 sm:mr-4 sm:float-left"/>The PHP Foundation Governing Board consists of a variety of folks from across the PHP ecosystem that share a vested interest in the success and sustainability of PHP. Representatives from the community, the core contribution team, and sponsors comprise this team to provide guidance and insight into the Foundation's objectives and initiatives. After a unanimous decision, we are incredibly pleased to be adding <a href="https://www.linkedin.com/in/anneguionmccarthy/">Anne McCarthy</a>, Architect and Open Source Director for Automattic, to our Board as a platinum sponsor representative.</p>

<p>Anne brings 15 years of technical and open source experience, and has spent the last 12 years at Automattic, dedicated to improving the experience of the WordPress community of users and contributors alike. They bring a balanced mix of thoughtful empathy and deep technical knowledge and will be a tremendous asset to the Foundation moving forward.</p>

<blockquote>
  <p>Open source comes down to people trying, caring, and showing up to benefit the collective. This feels like an especially powerful act in today's world so it's a real honor to join the PHP Foundation Board to support those who have given so much to PHP and all the other projects built with it. -- Anne McCarthy</p>
</blockquote>

<p>You can find Anne mostly in Seattle, WA where mountains and dogs both fill their soul with a special kind of joy. Please join us in welcoming Anne to The PHP Foundation Governing Board!</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Kicking off the PHP Onboarding Initiative Special Interest Group]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/03/kicking-off-the-php-onboarding-initiative/"/>
            <updated>2026-08-03T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/08/03/kicking-off-the-php-onboarding-initiative/</id>
            <content type="html"><![CDATA[<p>One of the most common pieces of feedback we hear from the PHP community is that the newcomer experience could use some improvement, and that we may be losing new users because of it. This is something that we as a community can address, and it's why The PHP Foundation made it part of our <a href="https://thephp.foundation/blog/2026/06/11/integrating-community-feedback-into-foundation-strategy-part2/#3.-php-onboarding-initiative">strategy document</a> for the rest of 2026. Improving that experience matters a lot to us, because a better new user experience means more community growth and retention. We are launching the PHP Onboarding Initiative Special Interest Group to provide space for collaborative problem solving in this area.</p>

<p>Some of the identified issues in the PHP newcomer experience include:</p>

<ul>
<li><strong>Where to begin:</strong> It is difficult for new PHP users to know where to start. There are many resources and tutorials available, but it is hard to know which ones are updated and accurate, and the sheer number of them is overwhelming. Building and helping people find resources that cater to their needs is something that would be helpful for newcomers.</li>
<li><strong>Minding the gap:</strong> The <a href="http://php.net/docs">php.net Manual</a> is a fantastic resource, but it is more of a reference than an educational resource for beginners that are learning to code. There is a current gap between documentation for complete beginners and users who already grasp the basics and use the manual differently.</li>
<li><strong>Limited presence in formal education:</strong> PHP is largely missing in universities and bootcamps. Although there are some places in the world where PHP (or a related framework/project) is taught, the presence of PHP is inconsistent. There won't be a "one-size-fits-all" approach to building more partnerships with educational institutions. But this is something that we can figure out together. (Also, this may overlap with the mission of the <a href="https://github.com/ThePHPF/SIG-ambassadors">PHP Ambassadors</a> Special Interest Group that has already launched.)</li>
<li><strong>Finding your people:</strong> The onboarding experience differs greatly among newcomers, with some having connections to the community, and others fending for themselves. It would be ideal if we could provide a more consistent approach to bringing newcomers together and connecting them with the community.</li>
<li><strong>Mentorship is hard to find:</strong> Although there have been previous attempts at mentorship programs, those have proven challenging to sustain. But <a href="https://www.linuxfoundation.org/hubfs/LF%20Research/LFX%20Mentorship%20in%20Open%20Source%20-%20Report.pdf?hsLang=en">research shows</a> that mentorship can make all the difference when it comes to retaining users and turning them into potential contributors and community members, especially when it comes to those from marginalized and underrepresented groups.</li>
<li><strong>Installation process</strong> Ensuring that this process is as easy and straightforward as possible, and centering the experience of new users is something that we should continue to be mindful of. Because this will likely involve the php.net website, this is another potential overlap with the mission of the <a href="https://github.com/ThePHPF/SIG-ambassadors">Marketing Subgroup of the PHP Ambassadors</a> Special Interest Group.</li>
</ul>

<p>These problems are not new and they aren't easy to solve, but one thing about the PHP community that I personally love is its dedication to sharing knowledge with new learners and helping newcomers find their way. This sense of community and support for newcomers is why many of us are still here (including myself!). Wouldn't it be great if we could come together and create a better and more consistent experience for newcomers to PHP?</p>

<p>If this is something that is of interest to you, we are hosting a kick-off meeting on <strong>Monday, August 24 at 13:00 UTC</strong>. To request an invite to this meeting, please register your interest using <a href="https://forms.gle/VNmijQm4gWjuDjnJA">this form</a>. Note: if you have already indicated your interest through this form, you do not need to submit it again.</p>

<p>If you cannot attend this meeting, that's okay! You are welcome to join the #the-php-foundation channel in the <a href="https://discord.phpc.social/">#phpc Discord server</a> for access to this and the other Special Interest Group chats. We also have a <a href="https://github.com/ThePHPF/SIG-onboarding">GitHub repository</a> where you can connect asynchronously.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Quarterly Progress Report - Q2 2026]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/07/21/quarterly-report-q2-2026/"/>
            <updated>2026-07-21T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/07/21/quarterly-report-q2-2026/</id>
            <content type="html"><![CDATA[<p>Our <a href="https://thephp.foundation/structure/#Core%20Developers">team of core developers</a> works very hard to strengthen and improve the PHP language. In an effort to improve the way we communicate this work, from now on, we will be posting quarterly updates regarding their individual projects and efforts.</p>

<p>Our core team consists of 13 people, distributed across 8 countries. Most of our contractors work part-time for The PHP Foundation and have other ventures aside from working on the PHP core. Also, this report is not meant to be a comprehensive list of everything our contractors shipped, but a high-level summary of their most impactful work.</p>

<p>In addition to our regular efforts around sustaining PHP through routine tasks like code reviews, bug fixes, issue triage and other maintenance work that we expect from all our developers, we want to highlight these particular efforts:</p>

<h3 id="arnaud-le-blanc">Arnaud Le Blanc</h3>

<p>Arnaud worked out a general solution to two long-standing sources of engine bugs tied to error handlers and destructors, in collaboration with Ilija Tovilo (one of Arnaud's fixes builds on an earlier attempt made by him). The forthcoming RFC will add a fix for a related third bug source, all targeting a version after PHP 8.6. On the STF project, he's stepped back from I/O hooks and shifted with Jakub Zelenka to <a href="https://github.com/php/php-src/pull/22538">a dependency of hooks</a>, also targeting a version after PHP 8.6.</p>

<h3 id="david-carlier">David Carlier</h3>

<p>David shipped <a href="https://github.com/php/php-src/pull/21631"><code>AF_PACKET</code> raw buffer support</a> in PHP's sockets extension, so PHP can now work with low-level Linux packet sockets directly instead of shelling out or resorting to FFI. This PR closes a real gap with C, Python, Go, and Rust, and opens up native packet capture and injection for PHP. It's also safe by design, since like every other language it needs a privileged account (<code>CAP_NET_RAW/root</code>) to use, so it doesn't widen the attack surface for ordinary code.</p>

<h3 id="derick-rethans">Derick Rethans</h3>

<p>Derick spent many hours investigating, trialing, and planning, and was able to complete a migration of the whole php.net infrastructure to a new CDN provider (more details on this are coming in a separate announcement).</p>

<h3 id="gina-banyard">Gina Banyard</h3>

<p>Gina worked on <code>ext/phar</code> to cut unnecessary string allocations and improve its clarity, and investigated unifying PHP's type-checking code to remove redundant return-type checks (tied to her interface-only generic types proposal), both of which reduce duplication and improve performance and maintainability. She also explored replacing the <code>get_constructor()</code> object handler with an attribute, which would make constructors more predictable and could eventually let <code>new MyClass(...)</code> be used as a callable. This is a small but long-requested ergonomics win. In parallel, she's been preparing the mass deprecation RFC for PHP 8.6, investigating how often objects get treated as arrays, and keeping up with PR reviews and older bug fixes to prevent technical debt from piling up ahead of the next release. On top of the engineering work, she represented the project publicly: preparing and giving a talk at UNSOUND (her first academic conference), along with other conference talks and an opinion blog post, helping raise the project's visibility outside its usual community.</p>

<h3 id="ilija-tovilo">Ilija Tovilo</h3>

<p>Ilija focused on ongoing security and regular issue handling and triage, work that keeps critical bugs from piling up and gets exploitable issues fixed before they reach users. He also continued work on the STF stream project, a core I/O abstraction where improvements pay off across many parts of the engine at once. In addition, he experimented with an 8-byte <code>zval</code> representation, which is a potentially high-leverage change, since <code>zval</code> is the fundamental value representation used throughout the engine, meaning a smaller size could meaningfully cut memory footprint and improve performance broadly. This is in the very early stages of experimentation. Finally, he drove improvements to <code>gcovr</code> accuracy from roughly 54% to 71%, giving the team a far more trustworthy picture of what's actually tested and better ability to catch under-tested code early.</p>

<h3 id="jakub-zelenka">Jakub Zelenka</h3>

<p>Jakub delivered several major new PHP core APIs, including a new stream errors API, an internal and userspace polling API (Io\Poll), and significant OpenSSL/TLS enhancements such as configurable session resumption, PSK support, and crypto status exposure. He also patched a security vulnerability in the FPM status endpoint and fixed a number of memory leaks and long-standing stream bugs. Together these changes strengthened PHP's streams, I/O, and TLS capabilities.</p>

<h3 id="james-titcumb">James Titcumb</h3>

<p>For the last few months, the PIE team has been hard at work on new features for the upcoming 1.5 release with several new key features. There's been a lot of background work to align the PIE interactions with Composer, which has allowed them to build several new requested features, including being able to install multiple extensions at once, adding a <code>--select</code> flag for unattended PIE installs for PHP projects, making re-installing an already installed extension a no-op, and being able to install locked extensions for a target PHP install with a new <code>pie install --from-lock</code> flag. Additionally, they have added support for some of the old PECL placeholder replacements, updated PIE to use the providers API, and kept up with maintenance of the 1.4.x series, bug-fixes, and security fixes for GitHub Security Advisories reported by the community.</p>

<h3 id="joe-watkins">Joe Watkins</h3>

<p>Joe's work has centered on experimenting with ideas that improve the PHP language and experience for contributors. His latest experiment was creating a multi-engine parser that would feed into a larger framework for mapping and connecting the PHP core code across repos, documentation, and eventually issues, PR comments, and other pieces of contextual information, which would help new contributors understand the context, evolution, and functionality of the PHP core codebase. This project was recently put on hold in lieu of other priorities, but is available on <a href="https://github.com/krakjoe/phathom">GitHub</a>.</p>

<h3 id="m%C3%A1t%C3%A9-kocsis">Máté Kocsis</h3>

<p>Thanks to Máté's work, the <a href="https://wiki.php.net/rfc/uri_followup">'Followup improvements for ext/uri' RFC</a> was accepted, and most of the work is already implemented. Once all changes land, it will become possible to build URIs and URLs via the new Builder classes, and some other, more advanced use cases will be better supported. Additionally, there is another RFC that has a fairly complete proposed implementation, which could revolutionize how query parameters are handled in PHP: <a href="https://wiki.php.net/rfc/query_params">https://wiki.php.net/rfc/query_params</a>. Voting is not yet open for this RFC but it should be open in the next quarter. Finally, Máté was also experimenting with UUIDs (UUID v7 more specifically) and created a proof-of-concept implementation for a new extension. Work on this will continue after the pending URI proposals are wrapped up.</p>

<h3 id="saki-takamachi">Saki Takamachi</h3>

<p>Saki was responsible for various bug fixes and code reviews and is currently out for family leave.</p>

<h3 id="shivam-mathur">Shivam Mathur</h3>

<p>Shivam added support for the new Visual Studio 2026 (VS18) toolchain across PHP's Windows build infrastructure and dependency stack, laying the groundwork the ecosystem needs ahead of PHP 8.6. He strengthened the security and stability of official Windows builds by updating and testing critical dependencies (OpenSSL, curl, SQLite, Apache, ICU, and libssh2), effectively closing off known vulnerabilities that could otherwise affect every Windows install. Shivam also resolved Windows-specific PGO and ZTS crashes, directly improving reliability for Windows users on currently supported versions. And lastly, he also maintained and improved php-windows-builder, keeping Windows binaries flowing for new PECL extension releases and keeping the platform from falling behind Linux/macOS in build support.</p>

<h3 id="volker-dusch">Volker Dusch</h3>

<p>Volker founded the <a href="https://thephp.foundation/blog/2026/05/18/announcing-ecosystem-security-team/">PHP Ecosystem Security Team</a>, a new effort to help PHP project maintainers find, fix, and handle security vulnerabilities. This is important because many maintainers, especially of smaller projects, lack the time or expertise to catch these issues themselves, leaving gaps that affect the wider ecosystem. Toward that end, he scanned over 500 of the most-used Composer packages and nearly every major framework, sharing 100+ fixes directly with maintainers, which translates into concrete, shipped security improvements across a large swath of the PHP ecosystem rather than just one project. He also worked alongside maintainers to help grow the team and support projects through specific security incidents (projects with a security need are encouraged to reach out).</p>

<h3 id="alexandre-daubois">Alexandre Daubois</h3>

<p>Our 13th contractor, Alexandre Daubois, is brand new to the team, so we won't have updates to share until the next quarterly report.</p>

<h3 id="the-php-foundation-leadership">The PHP Foundation Leadership</h3>

<p>In addition to our team of developers, The Foundation's Executive Director (that's me!) and Director of Fundraising (Ben Marks) have also been hard at work making progress on our goals. Q2 focused on getting a lay of the land through a listening tour, creating and kicking off implementation of a strategy plan for the rest of the year, and onboarding new contractors, sponsors, and Board members. We launched the PHP Ambassador program, quarterly Advisory Board meetings, the State of PHP Survey, revived the monthly newsletter, and began publishing <a href="https://github.com/ThePHPF/foundation/tree/main/board%20minutes">minutes</a> from the Governing Board meetings. We continue to focus on increasing Foundation transparency and collaboration with the community, and expanding our mission to include other initiatives besides PHP core language development.</p>

<hr />

<p>We are happy to share these updates with you, and if you have any questions about what any of our contractors are working on, you can connect with us in The PHP Foundation Discord channel on the <a href="https://phpc.chat/">PHPC server</a>.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Welcoming Alexandre Daubois to The PHP Foundation]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/07/14/welcoming-alexandre-daubois/"/>
            <updated>2026-07-14T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/07/14/welcoming-alexandre-daubois/</id>
            <content type="html"><![CDATA[<p>As you know, the main objective of The PHP Foundation’s mission is the sustainability of the PHP language, and a large part of that mission is focused on PHP core maintenance tasks. Included in this maintenance body of work are tasks such as issue triage, code reviews, and bug fixes. We take this responsibility very seriously, especially when it comes to security.</p>

<p>In recent months, there has been a marked increase in the number of security reports to <a href="https://github.com/php/php-src">php-src</a>, due to the increased availability of AI tools and the ease with which these reports can be generated. Some of these reports are not valid security issues or are basic duplicates of previously filed reports. But even so, every one of these reports must be triaged and validated, then if deemed valid, they must be classified, fixed, reviewed, and merged. There is a very small team that currently handles these reports, and it is becoming more difficult to not only keep up with the influx, but to address issues that already exist.</p>

<p><img src="/assets/post-images/2026/alexandre-daubois/alexandre-daubois.jpg" width="300" alt="photo of alexandre daubois giving a talk" class="mb-4 sm:mr-4 sm:float-left"/>As a result, we are thrilled to add <a href="https://www.linkedin.com/in/alexandre-daubois/?locale=en">Alexandre Daubois</a> to our team of contracted developers, focused on security. Alexandre will be spending a few hours a week helping with triage and the handling and fixing of incoming security reports.</p>

<p>As the current CTO of <a href="https://Les-Tilleuls.coop">Les-Tilleuls.coop</a>, Alexandre brings a wealth of experience in addressing and fixing security issues. He has deep knowledge of Symfony, FrankenPHP, PHP core, and Scrutineer, and has already been instrumental in implementing recommendations from The PHP Foundation’s Ecosystem Security Team. We are confident that his contributions will make a huge impact in our ability to process incoming reports and effectively harden the PHP language.</p>

<p>Please join us in welcoming Alexandre to The PHP Foundation team!</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Meet TYPO3: Supporting the Open-Source Foundation of Its Ecosystem]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/07/01/meet-typo3/"/>
            <updated>2026-07-01T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/07/01/meet-typo3/</id>
            <content type="html"><![CDATA[<p><a href="https://typo3.org/">TYPO3</a> has joined the PHP Foundation as a Silver Sponsor, extending its commitment to the open-source technologies and communities on which its own ecosystem is built.</p>

<p>TYPO3 is an open-source enterprise content management system built with open web standards. It provides a robust feature set for scalable, multisite, multilingual, and highly connected digital platforms. TYPO3 is also a verified Digital Public Good and part of the Open Website Alliance through the TYPO3 Association.</p>

<h3 id="php%3A-the-foundation-behind-typo3">PHP: the foundation behind TYPO3</h3>

<p>PHP has been the technological foundation of TYPO3 for more than two decades. It supports the CMS, its extension ecosystem, and the digital platforms built and maintained by TYPO3 agencies, contributors, and users worldwide.</p>

<p>TYPO3 also builds on other established open-source technologies, including Symfony components. Its support for the PHP Foundation follows the same principle as its financial backing of Symfony 8.1 and its sponsorship of PHPverse online events: projects that benefit from shared open-source infrastructure also have a role in sustaining it.
As a Silver Sponsor, TYPO3 contributes financially to the PHP Foundation’s work to support the continued development, maintenance, security, and stability of PHP.</p>

<h3 id="giving-back-to-the-php-ecosystem">Giving back to the PHP ecosystem</h3>

<blockquote>
  <p>“We're proud and grateful to support the PHP Foundation - because without PHP, there is no TYPO3. Its long-term health matters to our project, our community, and everyone building on top of TYPO3. By contributing as a Silver Sponsor, we are supporting the shared infrastructure we rely on every day.”
  --Frank Nägler, CTO, TYPO3 Company</p>
</blockquote>

<p>As a Silver Sponsor, TYPO3 is putting support behind the language that powers its CMS and many other projects across the open-source web. This sponsorship reflects a shared interest in keeping PHP secure, stable, and ready for what comes next.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Maintaining PHP Build infrastructure for Windows: Tooling for builds and security updates]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/06/26/maintaining-php-build-infrastructure-for-windows-tooling-for-builds-and-security-updates/"/>
            <updated>2026-06-26T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/06/26/maintaining-php-build-infrastructure-for-windows-tooling-for-builds-and-security-updates/</id>
            <content type="html"><![CDATA[<p>Most PHP developers never think about how PHP is built. They download it or install it using a command or a pre-built image and get started with their work. That is exactly how it should feel. A build system is doing its job when the final result looks great and works as expected.</p>

<p>Behind every official PHP for Windows release is a lot of infrastructure: compilers, SDKs, dependency libraries, extension compatibility, CI pipelines, and security updates that keep the supported PHP versions working.</p>

<p>As part of my work for The PHP Foundation, the focus has been on the Windows side of PHP: maintaining and improving the build infrastructure, updating dependencies, supporting extension builds, and making the process more reliable for current and future PHP releases.</p>

<p>This post is a look at that work, why it matters, and what goes into keeping PHP healthy on Windows.</p>

<h2 id="why-windows-support-still-matters">Why Windows support still matters</h2>

<p>PHP is widely used on Linux, as the most common use case is running web applications, but Windows support remains important for several reasons.</p>

<p>Many developers use Windows as their local development environment, and many companies run PHP applications on Windows servers. A lot of users depend on it for local testing environments, CLI tooling, and extensions that must work reliably on Windows. As per the <a href="https://survey.stackoverflow.co/2025/technology#1-computer-operating-systems">Stack Overflow annual developer survey in 2025</a> close to 50% of respondents use Windows for development.</p>

<p>Official PHP builds for Windows matter because they provide a trusted baseline and are part of the PHP project’s release process.</p>

<p>That means Windows support is not only about producing the final PHP build. It is about maintaining the full chain that makes a reliable PHP runtime possible.</p>

<h2 id="the-build-system-is-now-a-toolchain">The build system is now a toolchain</h2>

<p>Building PHP on Windows is very different from building PHP on Unix-like systems.</p>

<p>On Linux and macOS, building PHP usually depends on package managers for dependencies and easy-to-use popular build toolchains. On Windows, PHP uses a separate build system built around MSVC, Windows SDK that handles various MSVC versions, custom build scripts, and custom prebuilt dependencies with patches specific to PHP.</p>

<p>A PHP Windows build needs to know:</p>

<ul>
<li>Which Visual Studio toolset to use</li>
<li>Which Windows SDK to target</li>
<li>Which dependency packages are available</li>
<li>Which library versions are compatible with each PHP branch</li>
<li>Whether a build is x64, x86, thread-safe, non-thread-safe, debug, or release</li>
</ul>

<p>A major part of my work has been consolidating this into a modern toolchain: <a href="https://github.com/php/php-windows-builder">php/php-windows-builder</a>.</p>

<h3 id="php-extension-builds-for-windows">PHP extension builds for Windows</h3>

<p>We started with the purpose of making it easier to build PHP extensions on Windows. The goal was giving extension authors a path to produce builds that are compatible with the newer <a href="https://github.com/php/pie">PIE</a> direction. But because this new way of distribution for PHP’s extensions using PIE is still evolving, we also revived Windows builds for extension releases on PECL. As part of that, we have released builds for more than 100 actively maintained extensions.</p>

<p>That matters because Windows extension builds have historically been challenging for maintainers. Extension authors often do not have the full Windows build environment locally, and many contributors are more familiar with Linux-based workflows. A builder with a unified interface with known inputs gives the ecosystem a common place to test, debug, and improve Windows builds.</p>

<pre><code class="yaml">- name: Build the extension
  uses: php/php-windows-builder/extension@v1
  with:
    extension-url: https://github.com/xdebug/xdebug
    extension-ref: '3.5.3'
    php-version: '8.5'
    ts: nts
    arch: x64
    args: --with-xdebug
    libs: zlib
</code></pre>

<p>This is not only about convenience. It changes what is possible. For most extensions, building for Windows is as easy as copying one of the <a href="https://github.com/php/php-windows-builder/tree/master/examples">example workflows</a> we have.</p>

<h3 id="automating-windows-release-builds">Automating Windows release builds</h3>

<p>In addition to improving support for building PHP extensions, we also improved how the PHP runtime is built and maintained on Windows. We now have automated workflows in <a href="https://github.com/php/php-windows-builder">php/php-windows-builder</a> that build PHP on new tags in <a href="https://github.com/php/php-src">php/php-src</a>, run tests, deploy them to the <a href="https://www.php.net/downloads.php?os=windows">downloads server</a>, and make them available on the PHP website. This is a huge improvement on what used to be a manual process with delays, where the builds were run manually by one person in the Windows team and tested after publishing.</p>

<p><img src="/assets/post-images/2026/windows-build-infrastructure/php-windows-release-flow.svg" alt="Automated PHP for Windows release flow" /></p>

<h3 id="dependency-updates-and-testing">Dependency updates and testing</h3>

<p>As part of the PHP build infrastructure improvements, we also created a test bench workflow. It allows us to build PHP with unpublished builds of PHP dependencies directly from GitHub workflow artifacts rather than fetching them from the PHP servers. That allows us to test dependency updates.</p>

<p>Before this test-bench infrastructure existed, some dependency updates were delayed or avoided because testing them properly on Windows was too slow, too manual, or too challenging. With a dedicated builder and test bench, dependency updates can be tested more quickly across PHP branches and configurations. That helps us move faster on both compatibility and security work.</p>

<p>PHP 8.0 through PHP 8.3 use the Visual Studio 2019 toolset, while newer versions such as PHP 8.4 and PHP 8.5 use the Visual Studio 2022 toolset. PHP 8.6 will use the Visual Studio 2026 toolset. These transitions sound simple, but in practice they affect compiler flags, dependency builds, extension compatibility, CI base images, and long-term support decisions.</p>

<p>Keeping this working means constantly testing combinations of PHP branches, Visual Studio versions, and dependency packages. <a href="https://github.com/php/php-windows-builder">php/php-windows-builder</a> gives us a structured way to do that instead of relying on one-off manual builds.</p>

<h2 id="security-work%3A-cves%2C-dependency-updates%2C-and-backported-fixes">Security work: CVEs, dependency updates, and backported fixes</h2>

<p>A big part of maintaining PHP for Windows is security work.</p>

<p>That often means updating the dependency libraries that PHP and its extensions rely on when they receive CVE fixes or when new features demand it. These include libraries such as libcurl, OpenSSL, ICU, SQLite, libxml2, libjpeg, and more than 40 others.</p>

<p>When one of these libraries fixes a vulnerability, the Windows dependency stack has to be reviewed, rebuilt, and tested. The work is not as simple as bumping a version number.</p>

<p>A new dependency release can change ABI behavior, remove APIs, require another dependency to be rebuilt, expose new compiler warnings, or break an extension that used to compile cleanly.</p>

<p>For example, updating OpenSSL requires rebuilding curl and other libraries that depend on it. Updating ICU can introduce MSVC warnings or header-level changes that affect the <code>intl</code> extension. Updating Apache has to be evaluated carefully because PHP’s Apache module needs to remain compatible with the wider Windows ecosystem, including users running third-party installers <a href="https://mariadb.org/xampp-needs-more-apache-friends/">lacking maintainers</a>, but still have a large user-base.</p>

<p>There is also backporting work. Sometimes the safest path for a supported PHP branch is not to move an entire dependency stack forward, but to apply or adapt targeted security patches. That means reviewing upstream fixes, checking whether they apply cleanly to the version used by PHP for Windows, rebuilding the affected library, and validating that the patched build remains compatible with PHP and its extensions.</p>

<p>This balance matters. We want users to receive security fixes quickly, but we also need to avoid introducing regressions into supported PHP releases. Security maintenance on Windows is therefore a careful process of tracking CVEs, reviewing upstream changes, rebuilding dependencies, backporting fixes where appropriate, and validating the result through PHP’s test suites and real extension builds.</p>

<p>This is one of the less visible parts of the work, but also one of the most important. A secure PHP runtime depends not only on PHP source code but also on the native libraries that are shipped with it.</p>

<p><img src="/assets/post-images/2026/windows-build-infrastructure/php-85-cve-bin-tool-findings.svg" alt="Known CVEs detected in PHP 8.5 Windows builds" /></p>

<p>As part of this process, we updated these dependencies addressing a number of security issues reported for them over the last year.</p>

<table>
<thead>
<tr>
  <th>Dependency</th>
  <th>Old version</th>
  <th>Updated version</th>
  <th>Security issues resolved</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Apache</td>
  <td>2.4.43</td>
  <td>2.4.68</td>
  <td>CVE-2026-49975, CVE-2026-48913, CVE-2026-44631, CVE-2026-44186, CVE-2026-44185, CVE-2026-44119, CVE-2026-43951, CVE-2026-42536, CVE-2026-42535, CVE-2026-34356, CVE-2026-34355, CVE-2026-29170, CVE-2026-29167, CVE-2026-23918, CVE-2026-24072, CVE-2026-28780, CVE-2026-29168, CVE-2026-29169, CVE-2026-33006, CVE-2026-33007, CVE-2026-33523, CVE-2026-33857, CVE-2026-34032, CVE-2026-34059, CVE-2025-49630, CVE-2025-55753, CVE-2025-58098, CVE-2025-59775, CVE-2025-65082, CVE-2025-66200, CVE-2025-54090, CVE-2024-42516, CVE-2024-43204, CVE-2024-43394, CVE-2024-47252, CVE-2025-23048, CVE-2025-49812</td>
</tr>
<tr>
  <td>Firebird client</td>
  <td>3.0.6</td>
  <td>3.0.14</td>
  <td>CVE-2025-54989</td>
</tr>
<tr>
  <td>FreeType</td>
  <td>2.11.1</td>
  <td>2.14.3</td>
  <td>CVE-2022-27404, CVE-2022-27405, CVE-2022-27406, CVE-2025-27363</td>
</tr>
<tr>
  <td>libavif</td>
  <td>0.9.0</td>
  <td>1.4.2</td>
  <td>CVE-2025-48174, CVE-2025-48175, CVE-2023-6350, CVE-2023-6351, CVE-2023-6704</td>
</tr>
<tr>
  <td>libcurl</td>
  <td>8.17.0</td>
  <td>8.20.0</td>
  <td>CVE-2025-15224, CVE-2025-15079, CVE-2025-14819, CVE-2026-1965, CVE-2026-3783, CVE-2026-3784, CVE-2026-3805, CVE-2026-4873, CVE-2026-5545, CVE-2026-5773, CVE-2026-6253, CVE-2026-6276, CVE-2026-6429, CVE-2026-7009, CVE-2026-7168</td>
</tr>
<tr>
  <td>liblzma / XZ</td>
  <td>5.8.2</td>
  <td>5.8.3</td>
  <td>CVE-2026-34743</td>
</tr>
<tr>
  <td>libpng</td>
  <td>1.6.34</td>
  <td>1.6.56</td>
  <td>CVE-2026-33416, CVE-2026-33636</td>
</tr>
<tr>
  <td>PostgreSQL client</td>
  <td>14.18/16.9</td>
  <td>14.22/16.13</td>
  <td>CVE-2025-8713, CVE-2025-8714, CVE-2025-8715, CVE-2025-12817, CVE-2025-12818, CVE-2026-2003, CVE-2026-2004, CVE-2026-2005, CVE-2026-2006</td>
</tr>
<tr>
  <td>Cyrus SASL</td>
  <td>2.1.27</td>
  <td>2.1.28</td>
  <td>CVE-2022-24407</td>
</tr>
<tr>
  <td>libsodium</td>
  <td>1.0.18</td>
  <td>1.0.22</td>
  <td>CVE-2025-69277</td>
</tr>
<tr>
  <td>libssh2</td>
  <td>1.11.1</td>
  <td>1.11.1</td>
  <td>Patch for CVE-2026-7598 was backported</td>
</tr>
<tr>
  <td>libxml2</td>
  <td>2.10.4</td>
  <td>2.10.4</td>
  <td>Patches for the following CVEs were backported - CVE-2026-0989, CVE-2026-0990, CVE-2026-0992, CVE-2026-1757, CVE-2025-7425</td>
</tr>
<tr>
  <td>libxslt</td>
  <td>1.1.37</td>
  <td>1.1.43</td>
  <td>CVE-2024-55549, CVE-2025-24855, CVE-2025-11731, CVE-2025-7424, CVE-2025-10911</td>
</tr>
<tr>
  <td>nghttp2</td>
  <td>1.64.0</td>
  <td>1.69.0</td>
  <td>CVE-2026-27135</td>
</tr>
<tr>
  <td>OpenSSL</td>
  <td>3.0.18</td>
  <td>3.0.21/3.5.7</td>
  <td>CVE-2026-45447, CVE-2026-34182, CVE-2026-34183, CVE-2026-42764, CVE-2026-45445, CVE-2026-7383, CVE-2026-9076, CVE-2026-34180, CVE-2026-34181, CVE-2026-42766, CVE-2026-42767, CVE-2026-42768, CVE-2026-42769, CVE-2026-42770, CVE-2026-45446, CVE-2026-31790, CVE-2026-28387, CVE-2026-28388, CVE-2026-35188, CVE-2026-42765, CVE-2026-42771, CVE-2026-28386, CVE-2026-28389, CVE-2026-28390, CVE-2026-31789</td>
</tr>
<tr>
  <td>SQLite</td>
  <td>3.39.2</td>
  <td>3.53.2</td>
  <td>CVE-2025-7709, CVE-2025-70873, CVE-2025-7458.</td>
</tr>
<tr>
  <td>zlib</td>
  <td>1.2.12</td>
  <td>1.3.2</td>
  <td>CVE-2022-37434</td>
</tr>
</tbody>
</table>

<p>We also refreshed these dependencies to newer releases for bug fixes and new features.</p>

<table>
<thead>
<tr>
  <th align="left">Dependency</th>
  <th align="left">Old version</th>
  <th align="left">Updated version</th>
</tr>
</thead>
<tbody>
<tr>
  <td align="left">GLib</td>
  <td align="left">2.53.3</td>
  <td align="left">2.88.1</td>
</tr>
<tr>
  <td align="left">libwebp</td>
  <td align="left">1.3.2</td>
  <td align="left">1.6.0</td>
</tr>
<tr>
  <td align="left">libjpeg-turbo</td>
  <td align="left">2.1.0</td>
  <td align="left">3.1.4</td>
</tr>
<tr>
  <td align="left">LMDB</td>
  <td align="left">0.9.22</td>
  <td align="left">0.9.35</td>
</tr>
<tr>
  <td align="left">libiconv</td>
  <td align="left">1.17</td>
  <td align="left">1.19</td>
</tr>
<tr>
  <td align="left">libintl</td>
  <td align="left">0.18.3</td>
  <td align="left">1.0</td>
</tr>
<tr>
  <td align="left">libffi</td>
  <td align="left">3.3-4</td>
  <td align="left">3.5.2</td>
</tr>
<tr>
  <td align="left">Oniguruma</td>
  <td align="left">6.9.8</td>
  <td align="left">6.9.10</td>
</tr>
<tr>
  <td align="left">libenchant2</td>
  <td align="left">2.2.8</td>
  <td align="left">2.8.16</td>
</tr>
<tr>
  <td align="left">OpenLDAP</td>
  <td align="left">2.4.47</td>
  <td align="left">2.6.13</td>
</tr>
</tbody>
</table>

<h2 id="ci-has-become-essential">CI has become essential</h2>

<p>Modern PHP Windows work depends heavily on CI.</p>

<p>It is not enough to build PHP once locally and release it. We need repeatable testing across branches, architectures, dependency versions, and runtime combinations.</p>

<p>As part of <a href="https://github.com/php/php-windows-builder">php/php-windows-builder</a>, we now have a GitHub Actions-based approach to building PHP and its extensions; this is an improvement from the early days of building these on the Windows machine provided by Microsoft.</p>

<h2 id="preparing-for-the-future">Preparing for the future</h2>

<p>Windows support also has to look ahead.</p>

<p>One major area is architecture support. Historically, PHP for Windows has shipped x86 and x64 builds. But the value of x86 support continues to decrease as modern Windows systems are overwhelmingly 64-bit, while interest in ARM64 is growing.</p>

<p>That creates an important long-term question: what should the official PHP Windows build matrix look like in the future?</p>

<p>Dropping x86 and investing in ARM64 may make more sense for future versions. But that kind of decision cannot be made casually. It requires understanding who still depends on x86, what compatibility is actually being preserved, and what new users would benefit from ARM64 builds.</p>

<p>Part of the job is to make these transitions possible before they become urgent.</p>

<h2 id="in-closing">In closing</h2>

<p>Open source maintenance is invisible by design. If everything goes well, users do not notice that a dependency was rebuilt, a compiler issue was fixed, an extension was patched, or a CI workflow was improved. They just download PHP and continue working.</p>

<p>That is the goal.</p>

<p>But it is also why it is worth talking about this work occasionally. The reliability of a project like PHP depends on many layers of maintenance that happen outside the spotlight.</p>

<p>The Windows side of PHP has its own set of challenges, and continuing to invest in it helps keep PHP accessible to more developers, more environments, and more use cases.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[One Month of Ecosystem Security Engineering]]></title>
            <link href="https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/06/23/one-month-of-ecosystem-security-engineering/"/>
            <updated>2026-06-23T00:00:00+00:00</updated>
            <id>https://deploy-pr-320--thephpfoundation.netlify.app/blog/2026/06/23/one-month-of-ecosystem-security-engineering/</id>
            <content type="html"><![CDATA[<p>Last month I shared with you that the PHP Foundation secured a <a href="https://thephp.foundation/blog/2026/05/18/announcing-ecosystem-security-team/">grant by Alpha-Omega through the Linux Foundation</a> to help improve the security of the PHP open source ecosystem, and that it is forming a new Ecosystem Security Team. Today I want to update you on the progress so far.</p>

<p>After a brief set-up period, I jumped into three main activities:</p>

<ul>
<li>assessing PHP community members' most pressing needs</li>
<li>assembling a team of volunteers to help</li>
<li>applying the resources granted to scan PHP ecosystem projects</li>
</ul>

<p>Setup included getting started with building collaborative toolchains, ensuring access to scanning budgets and models, defining our metrics for reporting, and identifying effective ways to distribute security vulnerability findings and to support maintainers.</p>

<p>So far we talked to 35 project maintainers about our project scanning efforts and the security concerns they have. We shared hundreds of potential security vulnerability findings, leading to nearly a hundred publicly available fixes across the ecosystem already, and many great and useful conversations.</p>

<p>Additionally there were mass fixes of the same finding across many repositories. For example, in one case, we had around 200 repositories apply the same fix to their GitHub Actions as they are managed via a central template. I didn’t want to inflate the numbers so these instances are counted as a single fix.</p>

<p>In total, we scanned and rescanned over 300 of the most downloaded Composer packages and nearly all big frameworks. We got in touch with the respective maintainers or found people to jump in and help address security vulnerabilities where that was needed.</p>

<p>I want to extend a personal thank you to <a href="https://github.com/grahamcampbell">Graham Campbell</a>, who has been very helpful in getting me started with ideas and initial issue validation in the first couple of days of my new role and who has continued to be responsive and helpful with solving issues in other projects.</p>

<h2 id="current-efforts">Current efforts</h2>

<p>Project scanning for security vulnerabilities continues at a steady pace to make the most use of the resources we've been provided with. We do not only search for vulnerabilities, but also help triage, reproduce issues, help with impact analysis, and where necessary supply fixes by using our access to AI models and their extended “Cyber” capabilities.</p>

<p>I will continue to talk to everyone who approaches me while providing a steady flow of public-facing communication about our efforts.</p>

<p>All maintainers who approached me so far were kind enough to offer to validate the generated findings themselves. I was able to focus primarily on generating reproducers and letting the experts figure out whether a particular finding represents a security issue, a bugfix, or an invalid report. The maintainers in these cases were handling their own reporting and disclosure on their own terms and in a way that fits their timeline.</p>

<p>I’m personally delighted by the great community response, both quantitatively and qualitatively: Nearly everyone has been supportive and I encountered only one negative maintainer interaction and one person we are still looking to get in touch with. I couldn’t be happier with the maturity, readiness and friendliness of the wider community. I didn’t expect anything else from PHP, but it’s great to be proven right.</p>

<h3 id="shared-tooling%3A-scrutineer">Shared tooling: Scrutineer</h3>

<p>When scanning many projects, we face challenges: Getting reproducible and reliable outputs, avoiding false positives, and using our resources effectively without duplicating work, all while allowing each person scanning to run multiple agents in parallel without human interaction during the initial scanning process. Security analysis needs to be performed in isolated containerized environments that keep the infrastructure we use for scanning secure.</p>

<p>To pool our efforts, we are working with the Ecosystem Security Engineers from other languages and the Team at Alpha-Omega on shared tooling for this purpose. Specifically we're collaborating on <a href="https://github.com/alpha-omega-security/scrutineer">Scrutineer</a>. I want to give a special shout out to <a href="https://github.com/alexandre-daubois">Alexandre Daubois</a> from <a href="https://les-tilleuls.coop">Les-Tilleuls.coop</a>. His contributions to Scrutineer have been very valuable in enabling more people to effectively scan PHP projects.</p>

<p>Scrutineer enables more structured results and an easier reporting process. It also helps to let people with access to different, otherwise unavailable, AI models, or with access to more resource capacity, scan projects on our behalf. Using Scrutineer we can tailor the containers used for analysis towards the PHP ecosystem to improve the quality of scanning results through tooling to create and validate reproducers. The report quality would be drastically lower and require more clean-up work without effective automated feedback loops.</p>

<h3 id="helping-projects-with-individual-approaches">Helping projects with individual approaches</h3>

<p>We help projects and maintainers digest reports, create reproducers, deduplicate security vulnerability findings, and suggest and validate fixes.</p>

<p>When I accepted my new role, I was unsure how many projects would reach out for help with these tasks. I've received feedback that the quality of reports maintainers are receiving has gone up significantly in the last couple of months. So I've not received many requests to assist with processing reports and proposed fixes. Many maintainers report that they use their own coding agents to validate and reproduce received security vulnerability findings effectively. But for some more complex issues, currently available AI models cannot help or refuse to help with working on an exploit for a potential vulnerability. In these cases, I can be of help.</p>

<p>Sometimes, the automated scanning doesn’t produce clear results or the threat modeling or attack vectors are not clear enough. In these cases, I spend time with each project to better understand what the AI models should be assessing and steer them in that direction.</p>

<p>A special mention here is the PHP project itself: Many people like to try their new security tools on PHP, due to its popularity. The inherent complexity of a programming language runtime results in significantly lower quality results from agentic security approaches. The reports the PHP project receives are harder to digest than they are in userland PHP libraries with a clearer threat model and attack surface.</p>

<p>I was not yet able to help PHP itself much so far, due to time constraints. I intend to work on core PHP a lot more in the coming months. The communication with the PHP core developer team is great and I’m eager to get properly started and see where I can help them.</p>

<h3 id="assembling-a-team">Assembling a team</h3>

<p>I was delighted to see that the PHP Foundation is launching <a href="https://thephp.foundation/blog/2026/06/11/integrating-community-feedback-into-foundation-strategy-part2/#community-special-interest-groups">Community Special Interest Groups</a>. One of them is the Ecosystem Security Team, which the PHP Foundation wishes to sustain far beyond the 6 months of the initial grant funding, so I've begun to assemble a team around these security and maintainer support efforts.</p>

<p>If you want to reach out and talk with like-minded people about security, you can find a couple of us in the #ecosystem-security channel on the <a href="https://discord.com/invite/RYajXKxuuK">phpc Discord</a>. The <a href="https://phpcommunity.org">PHP Community Foundation</a> was kind enough to create a channel for us and #the-php-foundation in general. I’m “@edorian” on there, if you want to say hi.</p>

<p>For sensitive topics, you can always <a href="https://thephp.foundation/blog/2026/05/18/announcing-ecosystem-security-team/#:~:text=Get%20in%20touch%20via%20email%3A%20volker%40thephp.foundation.">get in touch</a> with me directly.</p>

<p>Next to Alexandre, who I already mentioned above, a name I’ve come across a lot when talking to maintainers was <a href="https://github.com/iliaal">Ilia Alshanetsky</a>. Ilia has been doing a lot of independent work and I asked him to join the Ecosystem Security Team so we can better coordinate our efforts.</p>

<h2 id="looking-ahead">Looking ahead</h2>

<p>The goals I set myself for the next month are:</p>

<ul>
<li>Scan another 250 projects and report all collected findings</li>
<li>Perform a dedicated, deeper analysis of core projects and libraries</li>
<li>Spend more time helping out with php-src and PHP Extensions issues</li>
</ul>

<p>I will continue to be available to help any project maintainers who reach out.</p>

<h3 id="get-in-touch">Get in touch</h3>

<p>To repeat what was already mentioned above: We have capacity to scan and help more maintainers.</p>

<p>Discord: <a href="https://discord.com/channels/356354025865740288/1507370983013744681">#ecosystem-security</a> on the #phpc community server <a href="https://discord.com/invite/RYajXKxuuK">(Invite)</a></p>

<p>Email: <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#x6f;&#58;&#x76;&#111;&#x6c;&#x6b;&#101;&#x72;&#64;&#x74;&#x68;&#101;&#x70;&#104;&#x70;&#x2e;&#102;&#x6f;&#117;&#x6e;&#x64;&#97;&#x74;&#105;&#x6f;&#x6e;">volker@thephp.foundation</a></p>
]]></content>
        </entry>
    </feed>