7  The Sock Puppets

The turn arrived as a reply to a patch. In April 2022 a contribution from “Jia Tan” sat on xz-devel, waiting on the attention of the one person who could merge it. On April 28 an account no one on the list had seen before posted its first message into that thread.1 The sender signed himself “Jigar Kumar,” and he dispensed with introductions. “Patches spend years on this mailing list,” he wrote. “5.2.0 release was 7 years ago. There is no reason to think anything is coming soon” (xz-devel mailing list 2022, msg00557).

The complaint, as a complaint, had a defect that took two years to surface. The slowness was real; the release the message mocked was genuinely seven years old, and a frustrated stranger is part of the weather of any open-source mailing list. But the specific neglect on display did not exist. By the time “Jigar Kumar” appeared, Lasse Collin had already merged four of “Jia Tan’s” patches, each recorded in the project’s history with a “Thanks to Jia Tan” in the commit message (Cox 2024). The maintainer being accused of ignoring the newcomer’s work was, by the visible record, accepting it steadily. Evan Boehs, whose timeline became the reconstruction much of the later reporting leaned on, marks this as the moment the operation acquired a second voice: a patch arrives from “Jia Tan,” and a new persona enters to press for it (Boehs 2024). Dan Goodin’s account in Ars Technica, written for readers a long way from any mailing list, compresses the sequence to its shape: a patch is submitted, and “almost immediately” a “never-before-seen participant” joins the list to argue that the longtime maintainer is not keeping up (Goodin 2024).

Up to this point the operation’s story has been a story about code. From here it is a story about people. Accounts of the kind that began to gather on xz-devel in the spring of 2022 have an old name online: sock puppets, identities invented and worked by a hidden hand, which speak, like the toy, only because there is an arm inside. The chapter takes its title from the term, so the ground rule comes first. What the record documents is behavior: what the accounts wrote, when they wrote it, to whom, and what became of them afterward. That the accounts were coordinated, that they were created for the purpose, that they belonged to the operation at all, is inference, drawn after the fact by named observers whose judgments arrive, as will be seen, with their own hedges attached. The reconstruction that follows states the inference where the evidence invites it and keeps the line between the two in view throughout.

The second voice arrived three weeks later, on a front of its own. Collin also maintained XZ for Java, a separate implementation of the same compression format written in the Java programming language, and on May 19, 2022, an account calling itself “Dennis Ens” opened a fresh thread about it: “Is XZ for Java still maintained? I asked a question here a week ago and have not heard back” (xz-devel mailing list 2022, msg00562). On its face it was the most ordinary message on the list, a user asking after a quiet project, listing the features he was waiting on, wondering whether to carry his own changes locally in the meantime. That ordinariness is worth pausing over, because nothing about the second front resembled the first. One voice was abrasive, the other patient and reasonable; one pressed on the C library, the other on the Java one; and no visible thread connected them except the thing they would, over the following month, converge on.

The convergence came on June 7, when “Jigar Kumar” stepped into “Dennis Ens’s” Java thread with the campaign’s goal stated aloud. “Progress will not happen until there is new maintainer,” he wrote. “XZ for C has sparse commit log too. Dennis you are better off waiting until new maintainer happens or fork yourself. Submitting patches here has no purpose these days. The current maintainer lost interest or doesn’t care to maintain anymore. It is sad to see for a repo like this” (xz-devel mailing list 2022, msg00566). To fork a project is to copy its code and carry on development independently, the open-source world’s standing threat of last resort. The entire campaign is in that message in miniature. The demand is named: a new maintainer. The target is the maintainer’s character rather than the code: he “lost interest or doesn’t care.” And one stranger now addresses another by first name, as though a community of the dissatisfied had formed, a chorus performing consensus in the open for an audience of one.

Collin answered the next day. His reply is the message an earlier chapter read closely, the one in which a maintainer under pressure disclosed that his ability to care had been limited by “longterm mental health issues,” reminded the list that the work was an unpaid hobby project, and mentioned that he had been working off-list with “Jia Tan,” who might come to have a bigger role (Collin 2022). What belongs to this chapter is the reply’s closing thought: “Perhaps the moment after the 5.4.0 release would be a convenient moment to make changes in the list of project maintainer(s)” (Collin 2022). Six weeks of manufactured impatience had produced something no technical exploit could have: the maintainer himself, on the public record, floating a handover and naming the moment for it. Nothing had been taken. Something had been offered.

The chorus answered the concession by demanding it faster. “With your current rate, I very doubt to see 5.4.0 release this year,” “Jigar Kumar” wrote on June 14. “The only progress since april has been small changes to test code. You ignore the many patches bit rotting away on this mailing list. Right now you choke your repo. Why wait until 5.4.0 to change maintainer? Why delay what your repo needs?” (xz-devel mailing list 2022, msg00568). As a user’s complaint the message is strange. It names no defect, advocates no patch, asks nothing of the software at all. Its one subject is the calendar of the maintainer change, and its one effect, on a maintainer who had conceded the principle six days earlier, is to make the concession feel overdue. The spelling here and throughout is the messages’ own, preserved verbatim; the errors will matter later.

A week later the polite voice returned, and the campaign showed what it was. On June 21, “Dennis Ens” replied to Collin’s disclosure with a message framed as concern: Collin needed to recognize his limits, the community wanted more than the two projects were getting, and one of them should be handed off (xz-devel mailing list 2022, msg00569). It was the same demand dressed as solicitude. Thirteen days earlier, on this same list, under this same pressure, Collin had disclosed a private difficulty in one sentence. Now it was being returned to him as an argument for the handover. What that message did to the man who received it is not in the record, and this book does not guess. What the message did on the record is plain, and it is the strongest evidence in the correspondence that the pressure was engineered rather than ordinary. Genuine impatience is careless and diffuse; it wants the software fixed. This wanted what the other voice wanted, reached for the most personal material available on the list, and pressed on it in service of that single end. The cruelty, read soberly, is not color. It is the tell.

The following day the campaign made its direction unmistakable. “Is there any progress on this?” “Jigar Kumar” asked back in the patch thread where he had first appeared. “Jia I see you have recent commits. Why can’t you commit this yourself?” (xz-devel mailing list 2022, msg00570). It is the least dramatic message in the sequence and the most clarifying. The grievance was never speed. By late June the chorus was no longer asking Collin to work faster; it was asking, in the open, why “Jia Tan” did not yet hold the authority himself. The helpful insider of the previous chapter and the impatient outsiders of this one had converged on a single point, and the point was the keys.

“It worked.” The verdict is Russ Cox’s, in the commit-by-commit reconstruction this book has leaned on, and he delivers it flat: “It seems likely that they were fakes created to push Lasse to give Jia more control. It worked. Over the next few months, Jia started replying to threads on xz-devel authoritatively about the upcoming 5.4.0 release” (Cox 2024). By autumn the newcomer was speaking for the project’s next release; the first visible exercise of merge authority, on January 7, 2023, the previous chapter has already shown. Outside analysts read the campaign the same way. Thomas Roccia, a security researcher at Microsoft who assembled one of the early public reconstructions, described the extra personas as existing to press the maintainer “to change the maintenance itself to Jia” (Freund and Roccia 2024). Akamai’s researchers called the maneuver “an interesting form of social engineering”: fake accounts sending “myriad feature requests and complaints about bugs to pressure the original maintainer” (Akamai Security Intelligence Group 2024). Their sentence runs a half step past the record in one respect, crediting the campaign with “causing the need to add another maintainer”; causation inside one person’s decisions is exactly what a documentary record cannot show, and what the sourced sequence supports is narrower: pressure, then a concession, then an authority that grew. The distinction is small and load-bearing, and it opens the question the rest of the chapter has to answer: what, precisely, marks these accounts as fake, and what merely reads that way in hindsight?

Start with what is documented. The accounts left no discoverable public lives. “Jigar Kumar is never seen again” after the pressure ends, Boehs records, and “Dennis Ens,” writing from “a similar name+number formatted email,” is likewise “never seen outside of xz discussion,” with no associated accounts ever discovered for either (Boehs 2024). Both addresses follow one template, a name and a number at a free webmail service. The reporters at The Intercept who went looking for the people behind the names produced the cleanest portrait of what they found, which was nothing: “The users involved in the complaints seemed to materialize from nowhere — posting their messages from what appear to be recently created Proton Mail accounts, then disappearing. Their entire online presence is related to these brief interactions on the mailing list dedicated to XZ; their only recorded interest is in quickly ushering along updates to the software” (Mazurov 2024). The hedges in that portrait, “seemed to,” “appear to be,” are the reporters’ own, and they are the right ones. The absence of a footprint is documented; what the absence means is not.

The same reporting contributes the record’s one genuinely forensic datum. Where the chorus wrote from Proton Mail, an encrypted email service that generates a cryptographic key when an address is set up, the keys associated with the accounts “were created on the same day, or mere days before, the users’ first posts to the email group” (Mazurov 2024). Identities minted on the eve of their first complaint are what a purpose-built chorus would look like. The reporting attaches the limit in the same parenthesis, and the book keeps it attached: users can regenerate keys, so the addresses may be older than the keys they now carry. Suggestive, not dispositive. The template itself, though, proved legible the moment anyone had reason to look. Two years on, when accounts of the same shape turned up in Debian’s bug tracker hurrying the backdoored release toward the distribution, a push a later chapter reconstructs, the veteran Debian developer Thorsten Glaser named the pattern in a sentence: “all three of the involved ones were ‘string + number @ freemailer’ #JiaT75 sockpuppets” (Hess 2024, msg #87). His judgment came after the backdoor was public, which is the point. The heuristic is simple, and no one had reason to run it in time.

Everything about coordination and purpose past this point is analysis, and the honest analysts say so. Molly, the EFF systems administrator the previous chapter quoted on the operation’s patience, told The Intercept that new, history-less accounts appearing to coordinate on specific goals at key moments “fits the pattern of using networks of sock accounts for social engineering that we’ve seen all over social media,” and then supplied the sentence this chapter is obliged to keep stapled to that assessment: “Of course, it’s also possible these are just coincidences” (Mazurov 2024). The academic reconstruction by Piotr Przymus and Thomas Durieux reads the accounts as “likely created to add credibility and pressure,” part of “a pattern that retrospectively appears suspicious” (Przymus and Durieux 2025, 92); likely and retrospectively are doing honest work in that sentence. Kaspersky’s analysts, who compiled the fullest inventory of the three identities involved, the JiaT75 GitHub account, the lookalike free-mail addresses, an Internet Relay Chat handle, the mailing-list messages, and the code itself, noticed two things at the layer where personas are built: the identities’ implied geographies were conspicuously scattered, “perhaps to dispel hints of coordination,” and “[m]isspellings and grammar mistakes are similar across the three identities’ communications” (Kaspersky GReAT 2024). That observation is why the quotations in this chapter preserve every error: in the analysts’ reading, the shared mistakes are the nearest thing the record holds to a fingerprint. None of this is proof, and none of it is offered as proof. It is a convergence of independent readings on one inference: that the chorus had a single author, or a single employer.

If the inference is right, the method has a name and a manual. The pattern, The Intercept observed, fits “what’s known in intelligence parlance as ‘persona management,’ the practice of creating and subsequently maintaining multiple fictitious identities”; a leaked document from the defense contractor HBGary Federal sets out the meticulousness the craft can involve, down to the construction of an elaborate online life for each invented person (Mazurov 2024). The campaign’s personas conspicuously lacked one; the elaborate footprint the tradecraft prescribes was, in the same reporting’s words, “decidedly missing.” The detail cuts two ways, and the book declines to pick. Thinness could be read as amateurism, or as economy: these identities needed to convince no investigator, only a tired maintainer on a quiet list, and they were built to that specification and no further. What the thinness says about who built them belongs to the chapter on the hunt.

Either way, the move itself is old. Thomas Rid, the scholar of disinformation whose history Active Measures follows a century of manufactured politics, describes the standing repertoire in terms that need no adaptation here: operations have always employed “influence agents and cutouts,” a cutout being the disposable intermediary who stands between an operation and its target, who “may pretend to be something they are not,” and “online accounts involved in the surfacing or amplification of an operation may be inauthentic” (Rid 2020). Rid also states, better than any source in the XZ Utils record, why none of this was visible from inside the mailing list: “It is very hard to distinguish . . . between a cunning influence agent on the one hand, and a genuine activist on the other.” In practice, he adds, “one individual can be both genuine and an exploited asset, a witting and unwitting collaborator at the same time” (Rid 2020). That edge matters for this story, because the grievance the chorus voiced was not invented. The seven-year release gap was real. The overextended solo maintainer was real. The complaint was, in the abstract, one that genuine users hold and sometimes state just as rudely. A demand does not have to be false to be exploited, and a campaign built from true materials is the kind hardest to see while it is happening and hardest to prove afterward.

Open source’s own handbook had described both the play and the costume, years earlier and with no enemy in mind. Karl Fogel’s guide to running free-software projects, which earlier chapters drew on for its portraits of maintainership, advises allied contributors, under the heading “Appear as Many, Not as One,” that “having several people chime in with agreement early on can help it along, by giving the impression of a growing consensus. Others will feel that the proposal has momentum, and that if they were to object, they’d be stopping that momentum” (Fogel 2020, 72). Fogel is describing legitimate coordination among colleagues who actually exist, and he flags the hazard even so. The sock puppets ran the malicious build of the same mechanism: a simulated consensus, several voices lending one proposal momentum, pointed at a single reader. The same handbook catalogs the figure the personas dressed as: the genuinely difficult community member, “not overtly rude” but a manipulator of process, who looks “for wedgepoints in the project’s procedures, to give themselves more influence than they might otherwise have,” and whose harm spreads quietly because “neither the behavior nor the damage it causes is apparent to casual observers” (Fogel 2020, 104). Every project of any age has met that person, and projects had learned to absorb him as a cost of openness. That is what made the costume effective. An insistent stranger with strong opinions about the repository is the most ordinary nuisance in open source. From inside the mailing list there is no way to tell the genuine article, who in Fogel’s account acts from temperament rather than calculation, from the same figure being operated as cover.

Even the choice of target was traditional. Maintainers have been pressured out of their posts by impatient users since before most of the modern internet existed. In the early 1990s the first two leads of Linux’s networking code, Ross Biro and then Fred van Kempen, each gave up the role under sustained community impatience; Glyn Moody’s history of the free-software movement quotes the community’s own Networking-HOWTO recording that users wanted something reliable and that pressure on van Kempen rose as it had on Biro (Moody 2001). That pressure was genuine, the ordinary friction of a young community wanting working software. The rhyme is the point: the force that wears down maintainers had existed for three decades. The campaign against Collin invented nothing. It synthesized a known, ambient force at higher concentration and aimed it with intent, which is also why it read as weather to everyone watching.

If the reading of the chorus as technique still carries a residue of hindsight, the strongest corrective arrived two weeks after the disclosure, from institutions reporting an attempt they had caught. In mid-April 2024 the OpenJS Foundation, the nonprofit home of JavaScript projects used by billions of websites, and the Open Source Security Foundation (OpenSSF) published a joint alert built on a firsthand account: the OpenJS council had “received a suspicious series of emails with similar messages, bearing different names and overlapping GitHub-associated emails,” imploring the foundation to update one of its popular projects to “address any critical vulnerabilities” while citing no specifics, and the author or authors “wanted OpenJS to designate them as a new maintainer of the project despite having little prior involvement” (Bender Ginn and Arasaratnam 2024). The foundations drew the comparison themselves, in print: the approach “bears strong resemblance to the manner in which ‘Jia Tan’ positioned themselves in the XZ/liblzma backdoor” (Bender Ginn and Arasaratnam 2024). The XZ Utils attack, the alert warned, “may not be an isolated incident.” For this chapter the OpenJS attempt is the contrast case the XZ Utils record lacks. Same shape: multiple names, overlapping addresses, manufactured urgency, a demand for maintainership without a history of contribution. Different outcome: the council recognized it and stopped it. A move that can be recognized and stopped is a technique, not a coincidence of rude strangers, and an institution catching it in the act is as close as the public record comes to showing the play from the defender’s side.

The alert then did something institutions rarely do in the middle of an incident: it published the pattern. Its list of suspicious patterns in social-engineering takeovers opens with three items that read as a postmortem of the xz-devel correspondence, though they were written as guidance for everyone: “[f]riendly yet aggressive and persistent pursuit of maintainer” by “relatively unknown members of the community”; a “[r]equest to be elevated to maintainer status by new or unknown persons”; and “[e]ndorsement coming from other unknown members of the community who may also be using false identities, also known as ‘sock puppets’” (Bender Ginn and Arasaratnam 2024). This is where the chapter’s title term stops being internet slang and becomes institutional vocabulary, defined in print by bodies responsible for the ecosystem’s security. Further down the list sits the sharpest entry: “[a] false sense of urgency, especially if the implied urgency forces a maintainer to reduce the thoroughness of a review or bypass a control.” Urgency, in that sentence, is not a mood but a weapon aimed at the one safeguard a tired volunteer still operates, the review itself, and the observation will be worth remembering when the backdoored release reaches the distributions and the hurrying begins again downstream. And the alert recorded scale: the OpenJS team had “recognized a similar suspicious pattern in two other popular JavaScript projects” and flagged its concerns to CISA, the American government’s civilian cyber-defense agency (Bender Ginn and Arasaratnam 2024). Whether any of those attempts shared an author with the XZ Utils campaign is precisely what the documented record cannot say. What it can say is that by spring 2024 the technique was visible across the ecosystem, which is a finding in its own right, and one the chapter on the hunt returns to: a method this reproducible implies an actor, or actors, capable of running it more than once.

Why does the technique work? The foundations’ alert answers as bluntly as any source in the record, in guidance addressed to maintainers at large: “These social engineering attacks are exploiting the sense of duty that maintainers have with their project and community in order to manipulate them,” and the interactions to watch for are the ones that “create self-doubt, feelings of inadequacy, of not doing enough for the project” (Bender Ginn and Arasaratnam 2024). That is the institutions describing a method, and the book reads it here as nothing else; what the campaign actually produced in Collin is his and not the record’s. But set the method beside the documented messages and the fit is exact. Every note the chorus struck was aimed at duty rather than competence: patches “bit rotting away,” a choked repository, a community that wanted more. No message claimed Collin’s code was bad. Every message implied his stewardship was insufficient, and insufficiency is the one charge that a culture that frames maintenance as a duty owed to users leaves a volunteer no answer to except more of himself. The kernel community’s burnout session, convened the following year and described earlier in this book, would catalog the lay registers of that vulnerability, the maintainer who is “ignored,” the maintainer who is “disrespected” (Chance 2023); mapping those registers onto this campaign is the book’s analytic gloss, not the session’s, but it is hard to reread the two voices, one supplying the disrespect and the other the disappointed patience, without noticing how cleanly they divided the work.

The deepest answer, though, came from the engineer who would eventually catch the backdoor. Andres Freund, a longtime open-source maintainer himself, read the pressure campaign after the fact, knowing exactly what it had been, and what struck him was not its artfulness but its familiarity. “I’ve seen people behave worse,” he said of the messages, worse from real people, writing under stable identities they had used for years (Freund 2024, 01:04:16). The observation deserves its full weight, because it explains the camouflage better than any analysis of tradecraft. A manufactured chorus of hostile strangers passed as genuine because genuine hostility toward maintainers is common enough, and routinely worse, that nothing in the campaign’s register stood out against the background. The operation did not have to imitate something rare. It imitated the ordinary abuse of the people who hold open source up, the standing weather an earlier chapter documented, and the imitation passed because the original is everywhere.

Strip the analysis away and keep only what is documented, and the residue is still striking in its shape: two accounts with no past and no future, arriving within weeks of each other; a grievance manufactured in the thread of the patch it served; a personal disclosure converted into leverage within thirteen days; a demand stated, repeated, and met. Add the analysis, marked as analysis, and the shape acquires a name: a persona-management campaign, thin in construction and precise in aim, run against a maintainer whose circumstances an earlier chapter laid out in full. What this phase attacked was not code. It attacked the norms that make open source work at all, the patience with strangers, the presumption of good faith, the duty felt toward users, and it worked because those norms were load-bearing and unguarded. The campaign had run for eight weeks, and it had its yield. The maintainer had floated his own succession in public, the successor was on hand and already trusted, and the strangers who had demanded it had begun to go quiet. What remained was the transfer itself: the keys, the privileges, and the peculiar, unaudited intimacy of an open-source handover. That is the next chapter.


  1. The archived message’s own date header reads April 28, 2022, the form cited here; Russ Cox’s timeline of the operation dates the same message April 22 (Cox 2024). The book cites the primary archive’s dates for the campaign’s correspondence throughout.↩︎