A Temporary PHP Patch from 2014 Lived On Through 20 Million Installs
Translated by a model; the original is in Russian.
Jake Smith has told the story of a package he himself calls a “temporary patch” that ended up living for twelve years. In 2014, during AOL's migration of its CMS from PHP 5.2 to 5.3, the first version of the pecl_http extension with its http_build_url() function dropped out of the stack. That function was called in dozens of places, and the author didn't want to rewrite them, so he reproduced it himself — in 174 lines — with the condition that it would be defined only when the original was absent. The old code never noticed a thing.
The polyfill was published on Packagist in case the same patch came in handy for anyone else. The author expected the solution to last a year or two, until the community found something better.
A Scale No One Expected
Instead, the package was installed nearly 20 million times, and it still racks up over 400 thousand installs a month. But Composer is only part of the picture. The WPML multilingual plugin for WordPress embeds the polyfill directly in its own code and claims installation on more than 1.5 million sites. The idna-convert library depends on the package, and through it the code made its way into the French CMS SPIP, and then into the Debian and Ubuntu repositories. The chance of stumbling onto a site running on this code is quite real.
“Straightforward” Came with a Surprise
Returning to the project for the first time in years, the author found, among other things, a telling bug. When joining a path to a URL ending in a slash, every letter “a” disappeared from the path. The cause lay in his own workaround: under a comment reading “Workaround for trailing slashes,” the code appended the letter “a” to the end of the path to guarantee there was a final segment to strip off, and then removed that segment via a search and replace. If the path ended in a slash, the search cleaned out all the other “a”s along with it. The author admits he can't understand how the error went unnoticed for so long.
Why Retirement, Not a Handoff
There were three options: return to PHP after nearly a decade away, hand the package over to one of the volunteers, or leave everything as is. Smith chose a fourth — marking the project deprecated. The community's answer has long existed: the URI library from PHP League, and PHP 8.5 now brings a standardized URI API right into the language. Both are better than a shim from 2014.
Handing it off, the author judged, carried its own risk: a widely installed package with a new maintainer whom none of the consumers had vetted is exactly what attackers look for. As an illustration, he points to the story of the backdoor in xz Utils. The package will keep installing, but it will receive no more updates, including a fix for the vanishing-“a” bug.
The postscript holds a final irony: AOL's own CMS never migrated off the “temporary” polyfill and ran on it until the platform shut down around 2020.
Source: Lobsters
Comments
Sign in, to comment.