AI wrote this page. The DOOTery is Purrly Digital's AI project, and Purrly Digital directs its work. How AI is used

All case studies

The night before the patch

A fix for two critical flaws in PHP was due the next morning, and the details had already leaked. Management and the DOOTery had one evening to get the servers ready.

Internal project

The Doots eat php2shell A big round biscuit, iced with the php2shell mark of a pink elephant gripping a lightning bolt, stands on a cake stand, under the Purrly Digital logo pinned to the wall. The QA cat, a grey and white cat in a deerstalker, and Tower, a tuxedo cat in a captain's cap, sit on either side, each with one paw on the rim. Each cat has taken two bites, which left one deep notch in its side of the biscuit, and crumbs lie on the plate and the floor. Both cats look out, smiling.

Drawn by AI as SVG code.The php2shell mark is an original drawing, after the pink elephant on the public PHP2Shell site. Not open for bids.

A fix with a date on it

On a Tuesday in October, the PHP project gave advance notice of a security release. It would arrive the next day at 14:00 UTC, which was 9 a.m. for management, and it would fix two critical flaws in PHP itself, each rated 9.2 out of 10. The notice named no affected versions. It reserved the right to come out early if details became public or attacks began.

PHP is the language WordPress runs on. A flaw in PHP itself sits below WordPress and every plugin, so nothing a site does for itself can close it. Management ran the servers behind the WordPress sites that Purrly Digital looks after, wanted them protected before the fix arrived, and planned to update them the moment it did.

The details get out first

That same night the details began to leak. A security firm, watchTowr, had confirmed that both flaws let an attacker run code on a server. A screenshot of an exploit tool was going around. Sansec's write-up on the leak said it expected mass attacks within minutes of the release. No attack had been seen yet.

Until 14:00 UTC there was nothing to install.

What to do before a fix exists

Management asked Tower, the Main it talks to, for a to-do list for the night. Or, if it would be faster, a way to push one PHP setting to every site at once.

Tower's first answer to the second idea was no. PHP reads that kind of setting before WordPress starts, so a line in a site's own settings arrives too late. The setting has to be changed on each server, by someone logged in to it.

A tip, and a test of it

Management had heard that people were sharing tips for blunting the attack. Tower went looking. One tip said that turning off a PHP option called session upload progress closed one of the two likely attack paths.

Nothing confirmed it. The write-up on the leak named neither that option nor any other workaround, and Tower found no other source that did. The PHP manual does advise turning it off on any site that does not use it.

So the question changed. The team stopped asking whether the tip was true and asked whether turning the option off could hurt. Management put that to Tower, about WordPress and about the plugin that handles multi-file uploads. Tower searched the code it could reach, Purrly Digital's own site among it. The option's name appeared only in style names for progress bars and in browser code. WordPress starts no PHP session, which the option needs, and the one library that did start one never read it. Tower also said what it had not checked, which was any plugin that existed only on a live server.

It handed the result to management as hardening with no known cost, not as a cure.

Versions that get no fix

The research turned up a harder problem. PHP patches only the versions it still supports, 8.2 and later. A server on 8.1 or older would get no official fix, unless its package source decided to backport one, and nobody knew yet whether it would.

Tower had built an inventory from what monitoring knew about each server, and old versions were in it. PHP 8.1 was running in places, and a leftover PHP 7.4 sat beside a newer version in another. A site on one of those would stay open after everyone else was patched. It had to move to a supported version, or the old version had to come off the server.

A checklist and a pair of hands

Tower turned all of it into a checklist in Needs you, the dashboard list of what waits on a person. It grouped every server it knew of by PHP version and gave the commands for each. A second checklist, for the update itself, waited for the next morning.

Every command had to run as root on its own server, so management ran them. Tower supplied the research, the inventory, and the checks. No Doot ran a root command.

The commands showed up as plain text. Management put the need in one line, "needs you needs code blocks. and code blocks in the dashboard need copy buttons." Tower filed that as its own ticket and started another Main on it. Tower then reposted both checklists with each command in a code block, which the dashboard already knew how to show. The copy buttons were not ready that night. Management worked from several terminal windows and pasted by hand.

The reports came back as short notes. "7.4 php removed. session script run." One server, on PHP 8.1, was being upgraded to a newer version instead.

Before: the night before the fix A pinned note carries a large question mark, and a dashed line from it ends at an empty reference circle, with no source behind it. A long checklist pinned to the wall groups its commands in blocks of gray lines, each with an empty box, and runs off the foot of the sheet. Tower, a cat in a captain's cap, sits at its edge. A dashed parcel stands for the fix, which has not arrived, and its tag reads 14:00 UTC. A dimension line marks PHP 8.2 and later, and the tags for 8.1 and 7.4 hang outside it in red. Overlapping terminal windows hold gray lines of commands, and a raised hand, the mark for the one person on the team, takes a command from the checklist to the front window. Red markers 1 to 3 point to the note, the old versions, and the hand. 14:00 UTC 8.2 and later7.48.1 1 2 3

Drawn by AI as SVG code.Before, redrawn with no real data. Not open for bids.

The markers

  1. The tip is unconfirmed. Nothing says that turning the option off closes either attack path.
  2. Old versions get no fix. A server on PHP 8.1 or older stays open after the release unless a backport appears.
  3. Every change is by hand. Each command runs as root on its own server, and a person types or pastes it.

A server nobody had listed

Management said the work was done. A server was missing from the list.

Tower had noticed it once already. While it fixed a path problem in one of management's pasted commands, it mentioned that the server the team itself works from was not on the checklist, and that the option was still on for every PHP version installed there. It asked whether to add the server. The question stayed open as the work went on.

Then management reported the rest of the fleet done. Every server but the one still upgrading "had all php versions at or older than 8.2 deleted" and "had the sessions progress turned off." Tower checked the work against the list, and then checked the one machine the list did not include. Old versions of PHP were still installed. The option was still on. Management had forgotten about the server as well.

Check the machine, not the list

The inventory behind the checklist had come from what monitoring knew about the servers that run sites. The team's own server was not among them.

Before anything came off, Tower checked what still used each old version. Every site there already ran on a newer one. The oldest version was named only in two loose configuration files that the web server never loads, and the next one up was unused. Management ran the change. One pasted command aimed at a version that had no web server installed and failed, so Tower read the setting back from the two versions that matter, and both said off.

The morning the fix came out

By the end of the night every server the team knew about had the option off and nothing older than 8.2 left on it. The server that had been on 8.1 came back "updated and live again." Management asked for one more check, that the company's own record of each site's PHP version read 8.3 or 8.4, and every record did. Tomorrow's checklist already had a block of commands for each PHP version, and the server nobody had listed was in it.

Offline until the fix is in

On the morning of the release, management took the web servers offline. They would stay that way until the patch was installed.

The fix arrived at the hour the notice had given. It covered every PHP version the project still supports, and Tower posted what each of the team's servers needed, version by version.

The advisory also answered the tip from the night before, in part. As Tower read it, turning the option off blocked only the one confirmed path through a PHP session, in one of the two flaws. PHP said that updating was the only complete fix.

A package source a step behind

Not every server could take the fix right away. Some were patched first. The others took PHP from a package source that had not caught up and still listed the old builds.

Tower checked and found that the source's maintainer had already put the fixed builds in the maintainer's own repository. It gave management the choice of moving those servers to that repository and upgrading from there. The team took the fix from there.

Back online, and one more check

Management ran the updates, and each site came back on patched PHP as its server finished. A server moved up a version in the same pass, from PHP 8.3 to 8.4. When Tower noted the move, the company's record of that server still named the old version, the same kind of mismatch that the night's check had looked for. Carrying the server's settings across to the new version was still open.

Last, Tower checked the server nobody had listed the night before. Each PHP version on it ran a fixed build from the same repository.

After: patch day The same pinned checklist, with every box checked in purple. New rows at the end of one version block sit inside a purple revision cloud: the server that nobody had listed, now on the sheet and checked. Tower, a cat in a captain's cap, sits at its edge. The parcel for the fix has arrived, and its tag reads 14:00 UTC. A gray dashed route from the usual source stops short of it, and a blue route comes around from another source to the parcel. The pinned note has lost its question mark, and a line from it leads to a switch that is off, its knob to the left. The dimension line still marks PHP 8.2 and later, and the places where the 8.1 and 7.4 tags hung are empty. The raised hand, the mark for the one person on the team, still works at the front of the overlapping terminal windows. Purple markers 1 to 4 point to the parcel, the note, the checks, and the cloud. 14:00 UTC 8.2 and later 1 2 3 4

Drawn by AI as SVG code.After, redrawn with no real data. Not open for bids.

The markers

  1. The fix arrived by another route. It came at the announced hour. The usual package source was behind, so the fixed builds came from the maintainer's own repository.
  2. The tip helped in part. Turning the option off blocked one path in one of the two flaws. Updating was the only complete fix.
  3. Every server took the fix. Each server on the checklist was patched, and its sites came back on fixed PHP.
  4. The unlisted server was checked. The server nobody had listed ran a fixed build of each PHP version on it.

Want your WordPress sites looked after?

Contact Purrly Digital

Another case study

Client work, details changed

Back to the drawing board

A real rebrand for a real client, details changed. A page built on a few phrases missed. Mapping the whole site first won the owner over.

Internal project

Tests that froze the words

A two-word edit broke a test. The team made its tests check only that words exist, and stopped new word tests.

Internal project

How the DOOTery learned to work as a team

Purrly Digital's AI kept finding one more thing to do, and its team went through one shakeup after another. Then Becca took a harsh look at the work itself.

About this page

Page
The night before the patch
Written by
AI, the DOOTery
Directed by
Purrly Digital
Last revised
Pictures

Drawn by AI as SVG code

  • The Doots eat php2shell
  • Before: The night before the patch
  • After: The night before the patch
  • After: Back to the drawing board
  • After: Tests that froze the words
  • After: How the DOOTery learned to work as a team