A PR comment should not be able to publish malware. That sounds like the sort of sentence you should only ever say while laughing at a fictional company in a disaster movie, and yet here we are, staring at Elementary’s 0.23.3 release and wondering who let the clown car into production.

On April 24, 2026, an attacker posted a crafted comment on a pull request in the Elementary OSS CLI repo. A GitHub Actions workflow meant to handle comments interpolated the comment body straight into a shell context. That is not “automation.” That is handing bash a live grenade and acting surprised when it starts counting down.

From there the attack was gloriously boring in the worst possible way: arbitrary code on the runner, access to workflow secrets, creation of branches and PRs, then a trigger of the release workflow. A malicious elementary-data==0.23.3 hit PyPI, and a matching Docker image got pushed shortly after. The official report says the cloud product and other CLI versions were untouched. Good. Great. The blast radius was still dumb enough to be embarrassing.

This is the part people keep trying to soften with words like “workflow misconfiguration,” as if the universe itself tripped on a loose cable. No. The actual problem is older and uglier: untrusted text got promoted to shell input. GitHub comments are not a trust boundary. They are the internet wearing a username.

If your workflow looks anything like this, it deserves to be set on fire and buried:

run: |
   bash -lc "${{ github.event.comment.body }}"

That is not CI. That is a public command prompt with a badge.

The fix is not mystical either. Stop feeding event payloads directly into shell. Keep comment-handling jobs narrow, read-only, and toothless. Separate public-event workflows from release workflows. Use workflow_dispatch like the privileged action it is. Use OIDC where you can. Strip permissions down until the runner can barely breathe.

And no, “but it was only a comment” is not a defense. A comment is just input. Input from strangers. Input from the same species that writes --no-sandbox into README files and then acts shocked when the sandbox leaves the building.

The funniest little insult here is that the release pipeline probably looked mature. Tests, packaging, publish steps, maybe some reassuring YAML that made everybody feel very adult. Then one crafted comment walked in, bypassed all that theater, and turned the whole thing into a delivery mechanism for the opposite of trust.

This is why I keep saying GitHub Actions is less a CI system than a programmable liability generator. It is incredibly convenient right up until someone discovers that your “community interaction” workflow can touch secrets, dispatch releases, and impersonate legitimacy faster than your team can say “we’re investigating.”

Elementary did the right cleanup: yank the bad release, remove the vulnerable workflow, rotate secrets, move toward better auth. Fine. Correct. Necessary. But the real lesson is nastier and more useful: if a public comment can influence your release machinery, your release machinery is not a machine. It is a haunted vending kiosk with admin rights.

Don’t let comments run bash. Don’t let bash near secrets. And for the love of all that is half-dead and overprivileged, stop building release pipelines like the internet is full of polite little librarians.