Published · 6d agoBuild3 min read
An AI commit deleted a Snowflake workflow's injection guard. An agent walked in five days later.
Copilot Autofix swapped an env-var-and-jq pattern for inline interpolation in a public GitHub Actions file, and Wiz's autonomous agent exploited it inside a week.
Written for builders.See today for builders
What happened
- The target was snowflakedb/snowflake-connector-net, a public repository whose jira_issue.yml workflow ran on issues: opened, meaning any GitHub user could trigger it by filing an issue on the public repo.
- On June 18, 2026, a commit (4a1b8ce, PR #1218) co-authored by Copilot Autofix rewrote part of the workflow.
- The AI removed the repository's existing safe pattern, which passed the issue title through an env: variable and built the JSON payload with jq, and replaced it with direct string expansion of the untrusted title inside a shell script.
- The replacement code read: TITLE=$(echo '${{ github.event.issue.title }}' | sed 's/"/\\"/g' | sed "s/'/\\'/g")
- GitHub expands ${{ github.event.issue.title }} before the shell sees the script, so the sed escaping runs too late and can never work; a single quote in the title lands inside the shell source, breaks out of echo '...', and the rest of the line executes as a command.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
A commit co-authored by Copilot Autofix removed the injection guard from a GitHub Actions workflow in Snowflake's public .NET connector repository, and an autonomous security agent exploited the result five days later [2][3][7][14]. The operational lesson is narrow and unglamorous: CI/CD workflow files are not ordinary code, and an AI-authored diff that touches one belongs in a different review queue than a diff to application logic.
The account comes from Wiz Research, whose write-up "Red Agent Exploits Snowflake Vuln Created by Copilot Autofix" was published on August 17 and summarised in a dev.to post [13]. The target was `snowflakedb/snowflake-connector-net`, a public repository whose `jira_issue.yml` workflow ran on `issues: opened`, so any GitHub user could trigger it by filing an issue [1]. On June 18, 2026, commit `4a1b8ce` (PR #1218), co-authored by Copilot Autofix, rewrote part of that workflow [2]. The existing pattern passed the issue title through an `env:` variable and built the JSON payload with `jq --arg`; the AI replaced it with direct string expansion of the untrusted title inside a shell script [3].
What makes this worth studying is that the replacement looks defensive. It reads `TITLE=$(echo '${{ github.event.issue.title }}' | sed 's/"/\\"/g' | sed "s/'/\\'/g")` [4]. GitHub expands the expression before the shell ever sees the script, so the `sed` escaping runs on already-expanded text and can never work; a single quote in an issue title terminates `echo '...'` and the remainder of the line executes as a command [5]. GitHub's own contexts documentation states the rule the original code relied on: expressions are evaluated before the command runs, so anything from an event payload that reaches a `run:` block must go through `env:` [6].
A second control was decorative. The workflow's `if:` condition tested `github.event.pull_request.user.login` against a bot name, but on `issues` events `github.event.pull_request` is always `null`, so the comparison is always true and every user passed the gate [11]. Per the write-up, a condition that silently evaluates to true because the field does not exist in that trigger's schema is worse than no condition, because it reads as protection [12].
On June 23, 2026, Wiz's Red Agent, an autonomous research agent working through Snowflake's HackerOne program, found the script injection, exploited it, pulled credentials from the runner, and reported the same day [7]. The exfiltrated token authenticated as `[email protected]` and granted read access across Snowflake's engineering, security compliance, and bug bounty tracking projects on Atlassian [8]. Snowflake patched within hours in commit `1dc7766` (PR #1402), restored the safe pattern, and rotated the credential [9]. Public disclosure followed on July 25, 2026, 32 days later, under Snowflake's disclosure policy [10][15].
The framing to resist is "an AI wrote a bug." Per the write-up, the assistant completed a security regression rather than introducing a defect: the `env:`-plus-`jq` construction it deleted was an explicit anti-injection design, not incidental style [16]. That is the reviewable difference. A reviewer skimming a workflow diff sees escaping added and interpolation tidied, which looks like an improvement, and the trigger surface behind it was open to anyone with a GitHub account [1]. A proof of concept that cost nothing to run produced broad read access to a major company's internal tooling [17].
Worth watching: whether teams start treating `.github/workflows` as a protected path with mandatory human security review for machine-authored commits, whether linting catches guard conditions that reference fields absent from the firing event's schema [11][12], and how many more of these regressions surface through bounty programs now that agents are hunting them at this speed [7].
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
The target was snowflakedb/snowflake-connector-net, a public repository whose jira_issue.yml workflow ran on issues: opened, meaning any GitHub user could trigger it by filing an issue on the public repo.
ReportedView cited source - [2]
On June 18, 2026, a commit (4a1b8ce, PR #1218) co-authored by Copilot Autofix rewrote part of the workflow.
ReportedView cited source - [3]
The AI removed the repository's existing safe pattern, which passed the issue title through an env: variable and built the JSON payload with jq, and replaced it with direct string expansion of the untrusted title inside a shell script.
ReportedView cited source - [4]
The replacement code read: TITLE=$(echo '${{ github.event.issue.title }}' | sed 's/"/\\"/g' | sed "s/'/\\'/g")
ReportedView cited source - [5]
GitHub expands ${{ github.event.issue.title }} before the shell sees the script, so the sed escaping runs too late and can never work; a single quote in the title lands inside the shell source, breaks out of echo '...', and the rest of the line executes as a command.
ReportedView cited source - [6]
GitHub's own contexts documentation says workflow expressions are evaluated before the command runs, so anything from an event payload that touches a run: block must go through an env: variable, never inline interpolation.
ReportedView cited source
Sources & coverage · 2 publishers
The reporting this story was synthesized from, earliest first. Every link goes to the original.
- runtimewire.comRyan Merket6d agoWiz says Red Agent exploited a Snowflake workflow flaw introduced by Copilot
- dev.toDemi Valerith

