Last updated: August 18, 2026 · By Vishal Swami, Founder & Lead AI Reviewer, AISagely
An autonomous AI agent from security firm Wiz found a script injection flaw in one of Snowflake's public GitHub repositories. It exploited the bug and reached Snowflake's internal Jira in five days. Wiz first said GitHub Copilot Autofix co-authored the vulnerable pull request. GitHub disputes that. Its internal review found the flawed code was written and merged by a human, not Copilot.
Short answer: Wiz's Red Agent exploited a GitHub Actions script injection bug in Snowflake's
snowflake-connector-netrepo, stealing a Jira API token via a crafted issue title. Wiz's blog credited GitHub Copilot Autofix as a co-author on the vulnerable PR; GitHub says a human wrote and merged the flawed code and Copilot wasn't involved. Snowflake patched it the same day it was reported, June 23, 2026.

I read the Wiz write-up, the Hacker News thread that corrected it, and GitHub's follow-up statement before writing any of this. The story changed shape twice in 24 hours. In my testing of how this kind of GitHub Actions bug actually works, I rebuilt the vulnerable pattern in a throwaway repo. That confirmed the quote-escaping failure Wiz describes is real, not just a theoretical injection path.
What actually happened to Snowflake
On June 18, 2026, a pull request merged into snowflakedb/snowflake-connector-net, a public Snowflake repository. It changed how the .github/workflows/jira_issue.yml workflow handled new GitHub issue titles. The workflow's job is mundane: when someone opens an issue, forward it into Snowflake's internal Jira. The old code used a safer pattern — an env: variable and jq --arg to parse the title. The new code replaced it with a shell one-liner that piped the raw issue title through sed inside an echo command.
That one-liner had a hole in it. A single unescaped quote in a GitHub issue title could break out of the echo string. That would inject arbitrary shell commands into the Actions runner. No authentication was required, just the ability to open a public GitHub issue. The squash-merge commit for that PR listed "Copilot Autofix powered by AI" as a co-author. That's how the story first got framed: an AI code-review tool approved a change that introduced a critical vulnerability without catching it.
GitHub pushed back on that framing after the story spread. Its internal review found the vulnerable lines were authored and merged by a human Snowflake engineer. GitHub says those lines "were not reviewed by or contributed to by Copilot," according to Wiz’s updated write-up. Wiz's own blog was edited to match: GitHub Copilot Autofix was a co-author on the pull request overall, and it checked the merged change without flagging the injection risk. It didn't write the vulnerable jira_issue.yml code itself. Both things are true at once. A Copilot-touched PR shipped a human-written bug. No reviewer, human or AI, caught it. That's the real story, and it's messier than the original headline.
How Wiz's Red Agent found and exploited it
Wiz runs an autonomous offensive-security agent it calls Red Agent. It scans public repositories for exploitable GitHub Actions misconfigurations. It flagged the jira_issue.yml workflow. It crafted a GitHub issue with a title containing a single quote followed by a shell command, then submitted it. The first payload used # to comment out the rest of the line, but that threw a syntax error. The agent read the error and adjusted its payload to close the shell string properly with ; echo '. It resubmitted. The second attempt worked: it exfiltrated a Jira API token, base64-encoded, to a listener Wiz controlled.
That token authenticated as a Snowflake service account. It granted read access to Snowflake's internal Jira, including engineering, security-compliance, and bug-bounty tracking projects. Wiz reported the finding to Snowflake through HackerOne the same day it confirmed access, June 23, 2026, a full account of which ran in The Hacker News’ coverage. Snowflake merged a fix within hours, restoring the original env: plus jq --arg pattern, and rotated the exposed Jira token the next day. Snowflake's statement was direct: "The disclosure was received on June 23, 2026, and it was immediately investigated and remediated, and our investigation found no evidence of unauthorized access" beyond Wiz's own test.
| Wiz's initial framing (Aug 17 blog) | What held up after correction | |
|---|---|---|
| Who wrote the vulnerable code | Implied Copilot Autofix authored/approved it | A human Snowflake engineer authored it; GitHub says Copilot didn't touch those lines |
| Copilot's actual role | "Co-author" that missed the flaw | Co-author on the broader PR; reviewed the merged diff without flagging the injection |
| How the bug was found | Wiz Red Agent, autonomous scan | Unchanged — confirmed by both Wiz and Snowflake |
| Exposure window | 5 days (Jun 18–23, 2026) | Unchanged |
| Data confirmed accessed | Snowflake's internal Jira | Unchanged — read access to a Jira token, no evidence of further lateral access |
No CVE has been assigned to this issue as of publication, and Snowflake says it found no evidence any other party accessed the token during the five-day window.
What you'll need to check your own repos
You don't need Wiz's tooling to check for this exact class of bug. You need shell access, ten minutes, and a list of your public repositories that run GitHub Actions on issues or pull_request_target events. Those are the triggers that let an outside, unauthenticated user supply the string your workflow then executes. If you use Copilot, Cursor, or another AI coding assistant for review, keep it open in a second tab. It's genuinely useful for spotting unescaped template expansion once you know what to ask it.
Step-by-step: audit your GitHub Actions for this exact bug
1. Find workflows triggered by untrusted input
Search your .github/workflows/*.yml files for on: issues, on: issue_comment, or on: pull_request_target. Any of these can be triggered by a stranger, and the event payload — issue titles, comment bodies, PR branch names — is attacker-controlled text.
2. Look for direct string interpolation into run: steps
The dangerous pattern is ${{ github.event.issue.title }} (or .body, .pull_request.head.ref, etc.) written straight into a run: shell block, especially inside echo, curl, or any command that gets piped further. That's exactly the pattern that broke in Snowflake's workflow.
3. Check whether it's passed as an environment variable instead
The safe version passes untrusted values through env: and reads them as $VAR inside the script, rather than letting GitHub's template engine expand them directly into the shell command. If your workflow does the latter, an attacker's quote or backtick becomes part of your shell syntax.
4. Watch for null-coalescing logic bugs, too
Part of what let this bug ship was a second, quieter issue: a check for github.event.pull_request.user.login on a workflow that also runs on issues events, where that property doesn't exist and silently evaluates to an empty string. If your permission checks reference event properties that don't exist for every trigger type, they can fail open instead of closed.
5. Run a dedicated scanner, not just a manual read
Tools like zizmor (an open-source GitHub Actions security linter) catch this injection pattern automatically across an entire repo, which scales a lot better than eyeballing every workflow file by hand.
6. Rotate any secret a vulnerable workflow could reach
If you find the pattern, assume the secret was reachable even if you have no evidence it was taken — Snowflake rotated its Jira token the day after patching, which is the right instinct regardless of whether logs show abuse.
Example prompts you can copy
- Spot the injection pattern: "Review this GitHub Actions workflow YAML for script injection risk: [paste]. Specifically check whether any
${{ github.event... }}value is interpolated directly into arun:shell command instead of passed throughenv:." - Explain a null-coalescing risk: "This workflow checks
${{ github.event.pull_request.user.login }}but also triggers onissuesevents. What does that property evaluate to on an issue event, and does that create a security gap?" - Draft the fix: "Rewrite this workflow step so the untrusted GitHub event value is passed as an environment variable and parsed safely instead of expanded directly into the shell command: [paste]."
- Triage after a disclosure: "Given this HackerOne-style report [paste], what secrets could the described GitHub Actions vulnerability have exposed, and what should be rotated first?"
Common mistakes to avoid
The mistake nearly every early write-up made, myself included on first read, is repeating "Copilot Autofix introduced the vulnerability" as settled fact. GitHub's own review disputes that authorship claim. Read past the headline before you cite this incident. Second, don't assume a low- or no-CVE incident is minor. This one had no CVE assigned and still exposed a live Jira API token for five days. Third, don't treat pull_request_target triggers as automatically dangerous and issues triggers as automatically safe. Both process attacker-controlled text, and the Snowflake bug lived in an issues-triggered workflow. Fourth, don't stop at fixing the one flagged line. Snowflake's fix also had to close a logic gap around the missing pull_request.user.login property, a separate root cause sitting next to the injection. Fifth, if you run a bug bounty or use HackerOne, don't assume same-day patching means same-day rotation of every credential the bug could reach. Confirm rotation as its own step in your incident checklist, not something the patch implies.
Tools that make this easier
If Copilot is your daily driver for code review as well as generation, it's worth understanding where it's strong and where a human still needs to read the diff line by line — my how to use Copilot and how to use GitHub Copilot in VS Code guides cover the review workflow, not just autocomplete. If you're deciding whether Copilot or an alternative catches more of this class of bug, GitHub Copilot vs. ChatGPT and Cursor vs. Copilot are both fair starting points before you lean on any single assistant for security review. For the workflow-file review itself, how to use Copilot in VS Code walks through inline suggestions on YAML and shell scripts specifically. This isn't the first story this year about AI cutting both ways in security — my piece on AI fueling over half of cybercrime in Africa covers the offensive side, and Z.ai’s public vulnerability ledger is the mirror image of this story: a lab proving its models find bugs like this one, in the open, instead of a security firm finding them after the fact.
My take
Strip away the "AI wrote the bug" headline and a more useful lesson is left. A human wrote an unsafe shell one-liner. An AI reviewer looked at the merged diff and didn't catch it. Five days later, an autonomous AI red-team agent found and exploited it on the open internet, with no human operator running the actual attack. That last part is the real news. Whether Copilot generated the vulnerable line or just missed it in review, the underlying pattern is the same: untrusted event text expanded directly into a shell command. That's a known, well-documented class of bug. A dedicated linter like zizmor would have caught it before merge. If you run GitHub Actions on public repos, the takeaway isn't "don't trust Copilot." It's "don't let any single reviewer, human or AI, be the only check on workflows that strangers can trigger."
Frequently Asked Questions
Did GitHub Copilot actually write the vulnerable code?
GitHub disputes that. Wiz's original blog credited "Copilot Autofix powered by AI" as a co-author on the pull request and initially implied it approved the flawed change. After GitHub's internal review, both GitHub and Wiz clarified that a human Snowflake engineer authored and merged the vulnerable jira_issue.yml lines; Copilot was a co-author elsewhere in the PR but didn't review or contribute the vulnerable code itself.
What data was exposed in the Snowflake breach?
A Jira API token belonging to a Snowflake service account (qa@snowflake.net), which gave read access to Snowflake's internal Jira, including engineering, security-compliance, and bug-bounty tracking projects. Snowflake says its investigation found no evidence anyone besides Wiz's Red Agent accessed the token during the five-day exposure window.
How was the vulnerability found and fixed?
Wiz's autonomous Red Agent scanned Snowflake's public snowflake-connector-net repository, identified a script injection flaw in a GitHub Actions workflow, and exploited it by opening a crafted GitHub issue. Wiz reported it via HackerOne on June 23, 2026; Snowflake patched the workflow the same day and rotated the exposed token the next day.
Is this vulnerability class free to check for in my own repos?
Yes. Searching your own .github/workflows/*.yml files for direct ${{ github.event... }} expansion inside run: steps costs nothing but time, and open-source scanners like zizmor automate the search across an entire repository for free.
Was a CVE assigned to this vulnerability?
No. As of publication, no CVE, CVSS score, or CISA KEV entry has been assigned to this issue, despite the confirmed credential exposure.