← All articles

GhostAction adds persistent stealer to 94 repositories

GhostAction adds persistent stealer to 94 repositories

GhostAction has expanded its supply chain attack from malicious GitHub Actions workflows to phishing and a credential stealer hidden inside a file presented as a web font. OpenSourceMalware identified the second-stage component in 94 compromised repositories and said it can remain active on a developer’s computer after the original workflow has been removed. A supply chain attack compromises software or its development process so malicious code can reach maintainers, projects and downstream users.

The campaign initially relied on GitHub Actions workflows, which are repository files that tell GitHub when and how to run automated jobs. OpenSourceMalware said the operator subsequently registered my-github[.]com on October 9, 2026 and directed it to 193.32.204[.]199. That address was already being used to receive information collected by the malicious workflow. The registration occurred 17 days after my-gitlab[.]com was registered, but investigators have not established that the same operator controls both domains. The infrastructure differs in its registrars, registration records, Cloudflare nameserver pairs, internet providers, IP addresses and DNS designs, and researchers found no shared certificate or account evidence.

On the day my-github[.]com was registered, it was used to send a phishing message to an open-source maintainer. Phishing is a deceptive message designed to make someone surrender account access or other sensitive information. Sent from noreply@my-github[.]com, the email impersonated a GitHub security notification and claimed that a suspicious login had occurred in Moscow, Russia. It directed the recipient to a link presented as a way to secure the account.

OpenSourceMalware said the linked page operated as a reverse proxy, an intermediary that relays traffic between a user and a genuine service while intercepting the session. It collected the victim’s password and two-factor authentication (2FA) code, then used injected JavaScript to authorize an OAuth application. OAuth is a method for granting an application access to an account without directly giving it the password. The requested repo, workflow and read:org scopes, which define the access being requested, allowed repository reading and writing, modification of Actions workflow files, and visibility into organization membership and related data.

The page also automated GitHub’s OAuth device flow. Its script obtained a device code and user code, loaded the device login page, extracted the relevant forms, inserted the user code and submitted the authorization through the victim’s authenticated, proxied session. The victim did not have to enter the device code or knowingly approve the application. The resulting access token, a reusable digital credential, was sent to my-github[.]com over TCP port 8443. With repository-level access, the operator could enumerate projects through GitHub’s application programming interface (API) and place malicious files under .github/workflows/.

The second stage was designed to move execution from GitHub’s systems onto developer computers. It added three files to affected repositories. The first was a Microsoft Visual Studio Code tasks.json configuration containing a runOn: folderOpen trigger, causing a task to start when the project folder was opened in VS Code. The second was public/fonts/fa-solid-400.woff2, which looked like a font but contained the credential stealer. The filename matched one used in the Fake Font/PolinRider campaign in January 2026. The third file was another GitHub Actions workflow intended to run if the local stealer did not execute.

According to OpenSourceMalware, the disguised payload searched for AWS keys, PyPI and npm tokens, Git logins, Kubernetes cluster credentials, SSH private keys, and credentials for Anthropic Claude and Google Gemini. These secrets can provide access to cloud resources, software publishing accounts, source repositories, clusters, remote systems and AI services. The VS Code task also installed a cron job, a scheduled command on Unix-like systems, that ran attacker-provided code every five minutes. Stolen information was transmitted to the same server using unencrypted HTTP on port 8080.

The fallback continuous integration (CI) workflow, which is an automated repository job, was based on the original malicious workflow but searched for additional credential formats. If its direct upload failed, it attempted to place the findings in a secret GitHub gist. OpenSourceMalware observed the workflow under eight filenames: lint.yml, ci-check.yml, build-check.yml, repo-health.yml, audit.yml, code-review.yml, test-suite.yml and cache-cleanup.yml.

The 94 affected repositories belonged to 66 owners. Fifteen had subsequently been deleted, renamed or made private. Among the 79 that remained accessible, many appeared inactive. One had not been changed for more than nine years, while 65 had received no commit for over a year. Abandoned repositories still matter because developers or automated systems may retain old copies, and credentials exposed through a workflow or local clone can remain useful until they are revoked.

OpenSourceMalware said GitHub began preventing the first-stage workflow from running on October 9. Attack waves on October 10 and October 12 consequently extracted no secrets. The second stage appeared six days after the block and did not require a GitHub-hosted runner because it could launch when a developer opened the folder locally. Researchers could not establish that GitHub’s intervention caused this change, only that the operator shifted execution to an environment outside those workflow controls.

Developers who may be affected should use a clean device to revoke GitHub access and tokens, change passwords, inspect repositories for the added files, rotate every credential available to the workflows and warn anyone who cloned the projects. OpenSourceMalware said the operator remains unidentified and appeared to have limited experience: the environment-variable filter missed most API keys, the home-directory scan could time out and lose its own results, and one IP address handled exfiltration, phishing and conspicuous internet scanning. That infrastructure overlap continued to expose infections through searches for the address.

For organisations reassessing developer access and repository exposure, AEU-I provides security-first IT, infrastructure and consulting. The incident shows why removing a malicious workflow alone may be insufficient when a repository has also delivered code that can persist on developer machines and copy credentials from several connected services.

Also available in: DeutschItaliano