Cyber Incident Victim: Xygeni
Date:
Mar 2026
Location:
Israel
Summary
Xygeni reportedthat an attacker gained access to a maintainer’s account and a GitHub App private key, using them to open pull requests that introduced a command‑and‑control implant into the xygeni/oxygeni‑action repository. Although the pull requests were blocked by branch protections, the attacker moved the mutable v5 tag to reference a malicious commit, allowing any workflow that referenced xygeni/oxygeni‑action@v5 to receive the backdoor. The implant remained active for several days before being detected through community reports, after which the tag was removed and the malicious commit was purged. Investigation found no evidence that the main branch was altered, no compromise of the vendor’s platform or customer data, and traced the breach to the over‑privileged GitHub App key.
| CIA Posture | Motives | Tactics, Techniques & Procedures |
|---|---|---|
| Available to members | 0 motives | 1 technique |
| Threat Actors | Type | Location |
|---|---|---|
| 0 actors | Available to members | Available to members |
Description
On March 3 2026 an attacker who had obtained access to a maintainer’s account and a GitHub App private key injected a compact command‑and‑control reverse shell into the xygeni/xygeni-action GitHub Action, disguising the malicious code as a “scanner version telemetry” step. Three pull requests carrying the implant were opened and then closed without being merged, but the actor subsequently moved the mutable v5 tag to point at the commit containing the backdoor. Because workflows that referenced xygeni/xygeni-action@v5 retrieved the tag’s target commit, any user of that tag during the period March 3 through March 10 unknowingly executed the C2 implant. Xygeni’s existing branch detection rules blocked the pull‑request attempts to merge the malicious code into the repository’s main branch, so no malicious commit was ever integrated into the main line of the action. The compromise remained undetected until community reports on March 9 alerted Xygeni to suspicious activity affecting the repository used to publish the action. Upon investigation Xygeni confirmed that the v5 tag had been poisoned after the malicious commit was created and before the tag’s alteration was discovered on March 9, although the exact timing could not be verified because GitHub does not log tag force‑push events.

Xygeni published a detailed security incident report on March 10 that included a timeline of the attack, a root‑cause analysis, and remediation recommendations. The report identified the compromise of a GitHub App private key with unnecessarily broad permissions as the root cause, noting that the attacker used a maintainer’s personal access token to create the pull requests and the GitHub App’s credentials to approve them, thereby bypassing repository protections that neither credential could overcome alone. The vendor stated that no evidence of compromise to its platform or customer data was found and that the compromised v5 tag had been permanently removed as part of its incident‑response procedures. Xygeni also acknowledged that the precise method by which the private key was exfiltrated remained under investigation, while noting that such keys can be exposed through misconfigured workflows, compromised developer machines, or insecure secret storage.
The StepSecurity blog post dated March 9 was the first public indicator of the breach, describing the seven‑day window during which the v5 tag delivered the C2 implant to downstream workflows. Xygeni contested certain details of the StepSecurity timeline, specifically the claim that the v5 tag was moved at 10:49 UTC on March 3 immediately after the pull requests were closed, explaining that its investigation could not confirm that timing due to the absence of tag‑force‑push logs. The vendor emphasized that the tag was poisoned sometime after the malicious commit existed and before the community discovered the issue on March 9, and it confirmed that the malicious tag had been removed and that no malicious code had entered the repository’s main branch.
