← Back to Feed CACHED · 2026-06-30 01:52:39 · CACHE_KEY CVE-2026-13744
CVE-2026-13744 · CWE-89 · Disclosed 2026-06-29

Improper neutralization of attacker-controlled content in Snowflake CLI versions prior to 3

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A SQL injection bug in the tool your data engineers use to talk to Snowflake — and worse, the tool your CI runner uses too

CVE-2026-13744 is a SQL injection in the Snowflake CLI (snow) in versions *prior to 3.19*. The CLI fails to properly neutralize attacker-controlled content when constructing SQL — specifically in dollar-quoted YAML spec literals fed to snow spcs service create / execute-job / upgrade, in SHOW ... LIKE patterns under the default STANDARD_ESCAPE_SEQUENCES=FALSE session, and in FQN.sql_identifier paths where single quotes weren't escaped. A crafted YAML spec file or fully-qualified name can break out of the intended literal and append attacker SQL that executes with the CLI user's Snowflake role.

Snowflake's HIGH / 8.3 rating is fair. The AV:N / AC:H / PR:N / UI:R / S:C / C:H/I:H/A:H vector captures it well: no auth on the CLI side (the CLI carries the user's auth), but user interaction is required and complexity is high because the attacker needs to land malicious YAML or identifiers in front of the victim. The Scope:Changed bit matters — when a developer runs snow against a poisoned spec, the SQL executes under that developer's Snowflake role, crossing the CLI/Snowflake trust boundary cleanly.

"Snowflake's vendor 8.3 holds up — CI/CD pipelines running snow CLI with elevated roles are the real blast zone, not interactive developers."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Plant attacker-controlled content

Attacker contributes a YAML service spec (e.g. via a pull request to an infra repo) or a manifest with a malicious fully-qualified identifier. The payload uses $$-sequence injection to escape dollar-quoted SQL, or crafted single-quote payloads in identifiers. Public Snowflake quickstart repos and shared snowflake.yml templates are realistic injection vectors.
Conditions required:
  • write access to a repo or registry the victim consumes
  • victim project uses snow CLI with spec files or programmatic FQNs
Where this breaks in practice:
  • PR review on infrastructure repos
  • branch protection in mature CI
Detection/coverage: Standard SAST has poor coverage for YAML-as-SQL-template injection; pre-commit hooks rarely flag this.
STEP 02

Victim invokes vulnerable snow subcommand

A developer or — much more dangerously — a CI/CD runner executes snow spcs service create -f spec.yml, snow spcs service execute-job, snow spcs service upgrade, or any subcommand that builds SHOW ... LIKE against attacker-influenced names. The CLI builds SQL by concatenating the attacker's payload into dollar-quoted literals or LIKE patterns.
Conditions required:
  • snow CLI < 3.19 installed
  • command run against the poisoned input
Where this breaks in practice:
  • UI:R requirement means a human or pipeline must trigger it
  • some shops pin tooling and lag on the vulnerable range
Detection/coverage: Snowflake QUERY_HISTORY will record the executed SQL after the fact; no real-time prevention without a fixed CLI.
STEP 03

Injected SQL executes under the CLI user's role

The attacker's SQL runs with the role bound to the CLI session — USE ROLE whatever the user/runner defaults to. Payload can CREATE a new user, GRANT itself privileges, INSERT INTO exfil tables on an external stage, or DROP regulated tables.
Conditions required:
  • CLI session bound to a usable Snowflake role
Where this breaks in practice:
  • Role separation if the dev/CI runs as a least-privilege role
  • network policies restricting Snowflake reachability
Detection/coverage: Snowflake ACCESS_HISTORY + LOGIN_HISTORY show the anomalous activity; a tuned SIEM rule on unexpected GRANT ROLE or stage exfil queries catches it.
STEP 04

Escalation via elevated CI role

If the CLI runs in a CI/CD pipeline configured with SYSADMIN or ACCOUNTADMIN (very common for IaC-style Snowflake deployments managed via snow or schemachange), the injected SQL inherits that authority. From there: create new privileged users, exfiltrate any warehouse the role can see, or persist via a stored procedure with EXECUTE AS OWNER.
Conditions required:
  • snow CLI used in pipeline with privileged Snowflake role
Where this breaks in practice:
  • Mature deployments use OAuth + short-lived tokens scoped to a least-privilege role
Detection/coverage: Anomalous CREATE USER / GRANT OWNERSHIP queries from CI service-account principals — straightforward to alert on.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed as of 2026-06-30. Not on CISA KEV.
Public PoCNo public weaponized PoC at disclosure; the Snowflake security advisory describes the $$ dollar-quote breakout and SHOW ... LIKE escaping issue, which is enough to reconstruct.
EPSSExpected low at disclosure (<1st percentile) — typical for client-side CLI bugs requiring UI.
KEV statusNot listed.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H → 8.3 HIGH. AC:H and UI:R are the friction points; S:C is what keeps it above 7.
Affected versionsSnowflake CLI all versions < 3.19.
Fixed versionSnowflake CLI 3.19 and later. No distro backports — snow is shipped via pip/brew/installers by Snowflake directly.
Exposure populationSnowflake reports >10K customer accounts; the CLI is the canonical IaC tool for SPCS (Snowpark Container Services) shops. Realistic install base in the low millions across data engineering teams and CI runners.
Disclosure2026-06-29 via Snowflake Security Bulletins.
ReporterSnowflake internal security / external research credit per vendor bulletin (verify against bulletin page).
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.8/10)

Stays HIGH because the decisive factor is the CI/CD blast radius: snow is canonically deployed inside pipelines running with elevated Snowflake roles, and a poisoned spec turns a PR into arbitrary SQL under those roles. Interactive-developer exploitation is bounded by UI:R and AC:H, but the pipeline-execution role multiplier prevents a downgrade to MEDIUM.

HIGH vulnerability mechanics and affected version range
MEDIUM real-world CI/CD adoption of snow CLI
LOW active exploitation likelihood in the first 30 days

Why this verdict

  • Friction is real but not disqualifying: AC:H + UI:R means an attacker needs to land malicious YAML or identifiers in front of a victim — credible via PR/template poisoning but not drive-by.
  • Scope:Changed earns the 7+ baseline: the CLI runs under the user's auth context and pushes SQL into the Snowflake control plane — that's a real trust boundary crossing, not just a local crash.
  • Role multiplier — CI/CD pipelines: snow is increasingly used in IaC pipelines bound to SYSADMIN/ACCOUNTADMIN. A poisoned spec in a PR build = warehouse compromise. This is the verdict floor and the reason a friction-only argument can't drag it to MEDIUM.
  • Role multiplier — interactive devs: typical data engineers run snow with scoped roles; blast radius is the schemas they already own. This is the MEDIUM half of the spectrum, but it doesn't set the floor.
  • No active exploitation, no KEV, no public exploit kit — the only reasons it isn't being pushed to CRITICAL.

Why not higher?

Not CRITICAL because there's no unauthenticated remote path, AC:H and UI:R jointly demand a credible delivery mechanism (poisoned repo, manifest, or social engineering), and there is no observed in-the-wild exploitation. CRITICAL would require evidence of weaponization or a default-deployed high-value target.

Why not lower?

Not MEDIUM because the affected component is a tool widely used in CI/CD with elevated Snowflake credentials — the role-multiplier floor (privileged automation context) holds the verdict at HIGH regardless of how clean your developer workstations are. Downgrading would require evidence that <1% of snow invocations carry SYSADMIN-or-above authority, which is the opposite of typical pipeline usage.

05 · Compensating Control

What to do — in priority order.

  1. Upgrade Snowflake CLI to 3.19 fleet-wide — Replace snow on every developer workstation, every CI runner, and every container image baked with the CLI. Pin >=3.19 in requirements.txt, brew formulae, and base images. Deploy within 30 days per the noisgate HIGH mitigation SLA; full remediation within 180 days per the remediation SLA, but pipelines should be fixed within days.
  2. Audit CI service-account Snowflake roles — Catalog every pipeline that runs snow and confirm the bound role is least-privilege. Anything running as SYSADMIN/ACCOUNTADMIN should be downgraded to a project-scoped role with explicit grants. Do this in parallel with the upgrade — vulnerability or not, this is the right posture.
  3. Require PR review for any YAML spec, manifest, or schemachange file — Branch protection + CODEOWNERS on *.yml, snowflake.yml, and SPCS spec directories. This breaks the poisoned-spec delivery vector regardless of CLI version.
  4. Alert on anomalous Snowflake control-plane SQL from CI principals — Build SIEM rules over SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY for CREATE USER, GRANT ROLE, ALTER USER ... SET PASSWORD, and COPY INTO <external_stage> queries originating from service-account users. These are the post-exploitation signals.
  5. Set STANDARD_ESCAPE_SEQUENCES=TRUE at account level if compatible — Doesn't fix the dollar-quote breakout but closes the backslash-LIKE path. Test in non-prod first; some legacy SQL depends on the default.
What doesn't work
  • Network ACLs around Snowflake — the attacker SQL runs from your own approved CLI client over your own approved network path. Network controls don't see the injection.
  • WAF / SAST on application code — this is a CLI tool bug, not your application's SQL. Your app-tier SQLi defenses don't cover it.
  • MFA on the Snowflake user — the CLI session is already authenticated when the injection fires; MFA gated the login, not the per-statement execution.
  • Snowflake Native App framework controls — those govern installed apps, not the CLI's outbound SQL.
06 · Verification

Crowdsourced verification payload.

Run on any host that has snow installed (developer workstation, build agent, container image). No special privileges needed — invoke as bash check-snow-cli.sh. Returns VULNERABLE for snow --version < 3.19, PATCHED for >= 3.19, UNKNOWN if the CLI isn't found.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verification: CVE-2026-13744 (Snowflake CLI SQL injection)
# Exit 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -u

FIXED_MAJOR=3
FIXED_MINOR=19

if ! command -v snow >/dev/null 2>&1; then
  echo "UNKNOWN: snow CLI not found in PATH"
  exit 2
fi

RAW="$(snow --version 2>/dev/null || true)"
# Expected format: 'Snowflake CLI version: 3.x.y'
VER="$(echo "$RAW" | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1)"

if [ -z "$VER" ]; then
  echo "UNKNOWN: could not parse version from: $RAW"
  exit 2
fi

MAJ="$(echo "$VER" | cut -d. -f1)"
MIN="$(echo "$VER" | cut -d. -f2)"

if [ "$MAJ" -gt "$FIXED_MAJOR" ]; then
  echo "PATCHED: snow $VER"
  exit 0
fi
if [ "$MAJ" -eq "$FIXED_MAJOR" ] && [ "$MIN" -ge "$FIXED_MINOR" ]; then
  echo "PATCHED: snow $VER"
  exit 0
fi

echo "VULNERABLE: snow $VER (< ${FIXED_MAJOR}.${FIXED_MINOR})"
exit 1
07 · Bottom Line

If you remember one thing.

TL;DR
By Monday morning: inventory every host and CI runner with snow installed (which snow, container image scans, pip lockfile greps) and pin snowflake-cli-labs>=3.19 in all build manifests. Per the noisgate mitigation SLA for HIGH, complete the CLI upgrade and pipeline role-scoping within 30 days; per the noisgate remediation SLA, drive long-tail workstation upgrades to closure within 180 days. Pair the upgrade with a one-time audit of which Snowflake roles your CI service accounts hold — if any pipeline runs snow as SYSADMIN or ACCOUNTADMIN, that's the real exposure and fixing it pays dividends beyond this CVE. No KEV, no active exploitation — so you do NOT need the hours-window override, but don't let this slip past the 30-day mark either.

Sources

  1. Snowflake CLI release notes 2026
  2. Snowflake Security Bulletins
  3. Snowflake CVE considerations (Native Apps)
  4. SYSTEM$CLIENT_VULNERABILITY_INFO reference
  5. Related: snowflake-connector-python write_pandas SQLi (GHSA-2vpq-fh52-j3wv)
  6. Snowflake CVE listing — OpenCVE
  7. CWE-89: SQL Injection
  8. CISA KEV catalog (check listing status)
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.