Routine GitHub Activity Turned Into an Attack Surface
A coordinated campaign has turned something as mundane as opening a GitHub issue into a potential foothold on software build systems. Researchers at Radware identified 83 malicious issues, pull requests, and comments posted on September 1, 2026, across 61 public repositories, with confirmed evidence that injected commands actually executed inside two separate GitHub Actions workflows.
The pace of the campaign suggests automation rather than manual effort: 77 of the malicious submissions appeared within roughly 43 minutes, followed by six more in a second burst lasting about two minutes. Among the projects targeted were Google’s LangExtract, the container scanner Trivy, Brave Browser, MLflow, ToolJet, and the PX4-Autopilot drone software — though inclusion on that list doesn’t mean every one of those projects was actually compromised.
How Plain Text Became Executable Code
The campaign exploited a well-known but persistent class of weakness in GitHub Actions: workflows that take user-supplied text — an issue title, a comment, a pull request description — and drop it directly into a shell script without proper sanitization. Many repositories run exactly this kind of automation to label issues, notify maintainers, or run basic checks whenever someone interacts with the project.
The attackers’ payloads relied on Bash’s command substitution syntax, written as $(). When a vulnerable workflow inserted attacker-controlled text straight into an executable shell command, Bash interpreted that embedded syntax as a command to run rather than as inert text — and wrapping the malicious string in double quotes, a common but insufficient defense, did nothing to stop it.
Once triggered, the payload ran the env command to harvest the workflow’s environment variables, Base64-encoded the result, stripped line breaks, and attempted to send the data out via a curl request.
A Single Collection Server, Dressed Up With HTTPS
Every verified malicious payload pointed to the same external address — 54.205.16[.]142 — over port 8443, with a unique identifier attached to each individual attempt to track which target had been triggered. Despite using a port number associated with HTTPS, the traffic was plain, unencrypted HTTP.
How damaging a successful trigger actually was depends entirely on what each specific workflow had access to. GitHub Actions secrets aren’t automatically exposed to every job in a repository, so the fact that a command executed doesn’t by itself prove an attacker walked away with deployment tokens or cloud credentials — but in workflows where sensitive secrets were in scope, the exposure risk is real.
Case Studies: PX4-Autopilot and workout-cool
In the PX4-Autopilot repository, a pull request disguised as a minor documentation fix carried its payload inside the PR title itself. A workflow designed to validate titles inserted that text into a Bash command that invoked Python, and logs captured a command-substitution warning along with output beginning with the string “GIF89a” — evidence the injected code had, at minimum, partially executed.
In the Snouzy/workout-cool repository, an issue-notification workflow inserted an attacker’s crafted title directly into a Bash variable assignment, again triggering a command-substitution warning. A follow-up attempt to reach a Discord webhook failed because the resulting request body was malformed JSON — a failure that complicates, but does not rule out, a successful compromise.
Radware has not confirmed that any secrets were actually stolen, that attackers gained write access to any repository, that source code was altered, or that any release was tampered with. Investigators also found signs that some of the accounts used to post the malicious content may themselves have been compromised, including at least one account owner who publicly denied submitting the malicious issue attributed to them.
Part of a Broader Pattern
This campaign sits alongside other recent incidents — including the GhostAction credential-theft wave and the tj-actions supply chain compromise — that used different techniques to reach the same target: secrets embedded in CI/CD pipelines. Maintainers are advised to:
- Pass untrusted, user-supplied text through environment variables rather than interpolating it directly into shell scripts.
- Avoid
evaland similar constructs when handling external input. - Scope workflow permissions as narrowly as possible, and separate low-trust automation (like issue triage) from privileged release pipelines.
- Rotate any credentials that may have been exposed, review audit logs, and investigate unexpected outbound network activity if command-injection evidence is found.
Leave a Reply
You must be logged in to post a comment.