Every engineering team knows the cold drop in the stomach when a CVSS 9.2 remote code execution advisory lands for the runtime powering their backend. On October 21, 2026, the PHP team shipped an emergency release fixing two critical vulnerabilities. encrypted1on1’s backend runs on PHP. Our hosted platform was updated practically right after the patch landed. But this release also became a real-world test of why we designed encrypted1on1 the way we did: why a worst-case server exploit never turned into a leak of your team’s most vulnerable conversations, and the radical transparency of what client-side encryption can — and cannot — protect.
What happened (and why it was a "patch now" moment)
On October 21, 2026, PHP versions 8.5.12, 8.4.27, 8.3.36, and 8.2.35 were published to address two critical security flaws: CVE-2026-109618 and CVE-2026-109619. Both carry a CVSS score of 9.2, and both allow an unauthenticated remote attacker to execute arbitrary code on the host.
Technical advisories from CERT-EU and independent security researchers confirmed that exploitation details were being discussed publicly and that working proofs of concept began circulating within hours. In operational terms, this was never a "we will bundle this into next month’s maintenance window" patch — it demanded immediate action.
encrypted1on1 runs on PHP 8.5 inside the official FrankenPHP container. The patched base container images were published to Docker Hub the same evening.
What we did
We rolled out the patched container across our infrastructure practically right after the release:
- Our hosted service was rebuilt on top of the patched PHP 8.5.12 image and redeployed with zero downtime.
- Zero code changes needed: Because our production Dockerfiles track the
php8.5tag, a standard container rebuild immediately pulled in the patched upstream runtime. - Audit & telemetry: We conducted a full log and anomaly audit across all edge proxies and application workers. We found zero evidence of scanning, exploitation attempts, or abnormal activity prior to or during the redeployment.
Why your 1:1 notes were never readable from the server, patched or not
This is the precise scenario where zero-knowledge architecture pays for itself.
In a traditional 1:1 tool or internal wiki — whether it’s hosted on a corporate cloud or a self-hosted VM — an unauthenticated RCE on the server is an existential disaster. The attacker spawns a shell, reads the database credentials from the environment, and runs a query. Instantly, years of confidential conversations are laid bare: performance anxieties, compensation friction, personal burnout struggles, and unfiltered feedback.
In encrypted1on1, the server is architecturally oblivious. All meeting notes, agenda topics, private check-in reflections, and draft feedback are encrypted directly in the participant’s browser using AES-GCM-256 before ever touching the network wire.
What our database stores is pure ciphertext:
- Answers and private reflections from both participants, published or draft;
- Comments, outcomes, discussion topics, and action items;
- Private retrospective notes;
- Goal progress check-ins and personal notes.
The cryptographic keys required to decrypt this content are derived on user devices from their passwords using memory-hard Argon2id. These keys never leave the client unwrapped. The server only stores wrapped and sealed envelopes that it cannot open.
Even if an attacker had dumped our entire production database and every volume on disk, they would have walked away with data they cannot decrypt without the individual participants’ passwords. That is the foundational premise of our architecture: we do not ask you to trust that our servers will never face a zero-day. A vulnerability in PHP, in an underlying C library, or in our backend code does not translate into an exposure of what people confided in their 1:1s.
The honest boundary: What end-to-end encryption does (and doesn’t) cover
We believe that trust in security comes from technical honesty, not marketing bravado. Here is the exact boundary of what cryptography protects during a server compromise:
1. Metadata is visible on the server. End-to-end encryption shields the substance of your conversations, but the server necessarily coordinates operational routing. An attacker with root server access could inspect account IDs, which users meet with whom, meeting recurrence cadences, and timestamps. Furthermore, by deliberate product design, a minimal set of company-level scaffolding is kept unencrypted: goal titles, target dates, completion status, and organizational question templates (so team leads can manage high-level roadmaps). The complete breakdown is openly documented in our threat model.
2. Encryption protects data at rest, not future code execution. encrypted1on1 is a modern web application: your browser loads JavaScript assets served by the host. If an attacker gains persistent code execution on the server, they could theoretically attempt to modify those served frontend bundles to capture a user’s passphrase the next time they log in. We defend against this through strict Content-Security-Policy (CSP) headers, immutable container images, and subresource verification. But no client-side encryption can completely prevent a compromised web host from attempting to alter client code delivered to future visitors.
The takeaway: End-to-end encryption transforms what would have been a catastrophic, retroactive data breach of all historical records into an urgent, but clean operational patching event. What was already written remains mathematically secure; patching the server promptly prevents future tampering. You always need both.
Updating your self-hosted instance (Step-by-step)
If you self-host encrypted1on1 with our Docker setup, updating takes less than two minutes and requires no database migrations or configuration changes.
Step 1: Pull the patched base image.
Our deployment script builds your application container, but Docker may reuse its locally cached base layer. Explicitly pulling ensures you receive the fresh PHP 8.5.12 runtime:
docker pull dunglas/frankenphp:php8.5Step 2: Rebuild and redeploy.
Run the standard deployment script from your project checkout:
PROD_COMPOSE_FILE=docker-compose.prod.yml ./docker/prod/deploy.sh(Or simply ./docker/prod/deploy.sh if your environment already sets the compose file).
The script automatically builds the image with your current code, recreates the container, runs migrations, refreshes the compiled container cache, and performs an internal health check.
Note: You do not need to git pull application code first if you only want the security patch. Rebuilding your current checkout against the updated base image applies the fix cleanly.
Step 3: Verify the PHP version inside the container.
Run a quick check against your running app container:
docker compose -f docker-compose.prod.yml --env-file .env.prod exec app php -vIt should report PHP 8.5.12 (or higher).
If you run encrypted1on1 on bare metal or through a custom PHP package manager, upgrade your PHP packages immediately and restart your PHP process (FrankenPHP worker or PHP-FPM). A running process retains the vulnerable binary in memory until restarted.
Closing thoughts: Trust mathematics, not promises
Security releases like this one will happen again — in PHP, in the Linux kernel, in OpenSSL, or in browser engines. No software vendor can honestly promise that their servers will never run a zero-day vulnerability for a brief window of time.
What we can promise — and what our open-source codebase allows you to inspect and verify independently — is that the private dialogue between you and your team is never entrusted to the server’s goodwill. When infrastructure wobbles, mathematics holds the line.
If you have questions about this release, our cryptographic design, or need assistance patching your self-hosted instance, join us on GitHub.
