This week, ASOS customers received something no retailer wants its brand attached to: a hostile push notification delivered through the company's own mobile app. The message claimed the retailer's Snowflake environment had been compromised and directed the company to contact the sender via Telegram — a classic data-extortion calling card. ASOS confirmed to Sky News that an unauthorized customer notification had been sent, stated it is investigating activity involving third-party platforms used to communicate with customers, and acknowledged that basic personal information — names and contact details — may have been accessed. Payment-card data and account passwords are not believed to be affected. Snowflake, for its part, told Sky News its investigation found no compromise of the Snowflake platform itself.
Strip away the headlines and this incident carries a lesson every defender should internalize: the most damaging channel an attacker can abuse is the one your customers already trust. You can have immaculate endpoint hygiene and still get burned by an API key sitting in a marketing automation platform, a Snowflake service account without a network policy, or a third-party engagement vendor with standing access to your customer graph. This post breaks down the likely attack mechanics, what to hunt for, and the concrete hardening steps that prevent this from becoming your headline.
Technical Analysis
What Actually Happened (and What We Can Reasonably Infer)
No CVE is associated with this incident, and based on ASOS's and Snowflake's statements, there likely isn't one. This appears to be a credential- and configuration-driven compromise, not a software vulnerability. The observable facts:
- A push notification was delivered through ASOS's legitimate app infrastructure, meaning the attacker had the ability to create and send a campaign — either via a customer engagement platform (e.g., Braze, OneSignal, Airship, Firebase Cloud Messaging-backed systems) or via ASOS's own messaging backend.
- The message's content — a Snowflake compromise claim plus a Telegram contact demand — mirrors the extortion methodology seen in the 2024 Snowflake-related customer breaches and the subsequent UNC5537 / ShinyHunters-style campaigns, where attackers used stolen credentials (often harvested by infostealer malware) to access Snowflake tenants lacking MFA, then extorted victim organizations.
- ASOS's reference to "third-party platforms used to communicate with customers" points squarely at the marketing/engagement SaaS layer as the delivery vector.
- Snowflake's denial of a platform-level compromise is consistent with prior incidents: the platform isn't breached — tenant credentials are.
The Attack Chain (Defender's View)
- Credential acquisition — Infostealer logs, credential stuffing lists, or phishing yield credentials for the Snowflake tenant and/or the engagement platform. Service accounts and legacy user accounts without MFA are the soft targets.
- Tenant access — Attacker authenticates to Snowflake from an unfamiliar IP/ASN (frequently residential proxies or VPS providers), often using
snowsql, the Python connector, or direct REST API calls rather than the web UI. - Data access — Queries against customer tables containing names, emails, phone numbers. Large result sets may be staged and exported via
COPY INTO @stageor aGETto local disk. - Channel abuse — Using stolen engagement-platform API keys or console access, the attacker creates a push campaign targeting all (or a large segment of) app users. The message includes extortion language and a Telegram handle to open a negotiation channel.
- Extortion — Public embarrassment plus claimed data theft is used to pressure payment.
Why This Works
Push notification platforms are engineered for reach, not restraint. A single API call with a valid key can message millions of devices in minutes. Most organizations apply far less scrutiny to who can send than to who can see the data. Meanwhile, Snowflake tenants are frequently onboarded with passwords only, no network policy, no MFA enforcement, and service accounts that never rotate. None of this requires an exploit — it requires valid credentials and permissive defaults.
Exploitation Status
- No CVE, no PoC, no CISA KEV entry. This is a technique, not a vulnerability.
- Credential-based Snowflake tenant compromise and subsequent extortion is a confirmed, actively used technique set in the wild since mid-2024 and remains current. Abuse of customer engagement channels as an extortion amplifier, as seen here, is an emerging and highly damaging twist.
Detection & Response
The detections below focus on the three observable behaviors in this incident: (1) anomalous Snowflake authentication and data access, (2) mass data export from a warehouse, and (3) unauthorized push campaign creation with extortion indicators. Tune thresholds to your baseline — a retailer doing nightly ETL will look different from a 50-person SaaS shop.
---
title: Snowflake Login from Unusual Source or Non-Browser Client
id: 3f2a9c41-7d6e-4b12-9a55-0c8d2e1f6a77
status: experimental
description: Detects Snowflake authentications from programmatic clients (snowsql, Python/JDBC/ODBC connectors) or failures followed by success, consistent with stolen-credential tenant access and extortion-style intrusions.
references:
- https://www.rapid7.com/blog/post/it-asos-incident-attackers-using-channels-customers-trust
- https://attack.mitre.org/techniques/T1078/004/
author: Security Arsenal
date: 2026/02/12
tags:
- attack.initial_access
- attack.t1078.004
logsource:
product: snowflake
service: login_history
detection:
selection_client:
REPORTED_CLIENT_TYPE|contains:
- 'SNOWSQL'
- 'PYTHON_CONNECTOR'
- 'JDBC'
- 'ODBC'
- 'GO_DRIVER'
selection_success:
IS_SUCCESS: 'YES'
condition: selection_client and selection_success
falsepositives:
- Scheduled ETL/ELT pipelines and BI tooling using connectors from known IPs. Baseline and filter by source IP and service account name.
level: medium
---
title: Snowflake Bulk Data Export to Stage
id: 8c1d5e72-4a93-4f08-b6e1-2d7a3c9f0b44
status: experimental
description: Detects COPY INTO operations writing large customer or PII table result sets to internal/external stages, a hallmark of Snowflake data-theft and extortion campaigns.
references:
- https://www.rapid7.com/blog/post/it-asos-incident-attackers-using-channels-customers-trust
- https://attack.mitre.org/techniques/T1567/
author: Security Arsenal
date: 2026/02/12
tags:
- attack.exfiltration
- attack.t1567
- attack.collection
- attack.t1530
logsource:
product: snowflake
service: query_history
detection:
selection:
QUERY_TEXT|contains:
- 'COPY INTO @'
- 'COPY INTO ''s3://'
- 'COPY INTO ''azure://'
- 'COPY INTO ''gcs://'
filter_etl:
USER_NAME|contains:
- 'ETL_SVC'
- 'DBT_'
- 'FIVETRAN'
condition: selection and not filter_etl
falsepositives:
- Approved data-pipeline exports. Maintain an explicit allowlist of export service accounts rather than suppressing the rule.
level: high
---
title: Push Campaign Containing Extortion or Telegram Indicators
id: 5b7e2f19-1c48-4d3a-8f66-9e0b4a2c7d31
status: experimental
description: Detects creation or send of a push/in-app notification campaign whose body contains Telegram handles, extortion language, or breach claims — indicative of hijacked customer engagement platforms. Requires ingestion of engagement-platform audit logs (Braze, OneSignal, Airship, Iterable, custom messaging service).
references:
- https://www.rapid7.com/blog/post/it-asos-incident-attackers-using-channels-customers-trust
- https://attack.mitre.org/techniques/T1657/
author: Security Arsenal
date: 2026/02/12
tags:
- attack.impact
- attack.t1657
logsource:
category: application
product: engagement_platform
detection:
selection_event:
event_type|contains:
- 'campaign_created'
- 'campaign_sent'
- 'push_send'
- 'message_published'
selection_content:
message_body|contains:
- 't.me/'
- 'telegram'
- 'snowflake'
- 'compromised'
- 'breached'
- 'ransom'
- 'contact us to'
condition: selection_event and selection_content
falsepositives:
- Legitimate incident-communication campaigns. Require dual approval on campaigns as a compensating control (see Remediation).
level: critical
// Hunt: Snowflake tenant access from new sources with large result sets (Sentinel)
// Assumes Snowflake LOGIN_HISTORY / QUERY_HISTORY ingested via connector or custom log table (SnowflakeLogin_CL / SnowflakeQuery_CL).
let lookback = 14d;
let knownIPs =
SnowflakeLogin_CL
| where TimeGenerated > ago(30d) and TimeGenerated < ago(lookback)
| where IS_SUCCESS_s == "YES"
| summarize by CLIENT_IP_s;
SnowflakeLogin_CL
| where TimeGenerated > ago(lookback)
| where IS_SUCCESS_s == "YES"
| where CLIENT_IP_s !in (knownIPs)
| where REPORTED_CLIENT_TYPE_s has_any ("SNOWSQL", "PYTHON_CONNECTOR", "JDBC", "ODBC", "GO_DRIVER")
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Logins=count(), Accounts=make_set(USER_NAME_s), Clients=make_set(REPORTED_CLIENT_TYPE_s)
by CLIENT_IP_s, bin(TimeGenerated, 1h)
| join kind=inner (
SnowflakeQuery_CL
| where TimeGenerated > ago(lookback)
| where QUERY_TEXT_s has_any ("COPY INTO @", "COPY INTO 's3", "customers", "pii", "contact")
| extend RowsReturned = tolong(ROWS_PRODUCED_d)
| summarize TotalRows=sum(RowsReturned), Queries=count(), SampleQueries=make_set(strcat_slice(QUERY_TEXT_s, 0, 200), 5)
by USER_NAME_s, bin(TimeGenerated, 1h)
| where TotalRows > 100000
) on $left.TimeGenerated == $right.TimeGenerated
| project FirstSeen, CLIENT_IP_s, Accounts, Clients, USER_NAME_s, TotalRows, Queries, SampleQueries
| order by TotalRows desc;
// Hunt: Outbound references to Telegram in marketing/messaging logs (engagement platform abuse)
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where Message has_any ("t.me/", "telegram", "compromised", "breached", "ransom")
| where Message has_any ("campaign", "push", "notification", "broadcast")
| project TimeGenerated, DeviceVendor, DeviceProduct, SourceUserName, SourceIP, Message
| order by TimeGenerated desc;
-- Hunt endpoints for Snowflake client tooling and staged customer-data exports
-- Useful when investigating which internal host or credential source was used for tenant access.
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)snowsql|snowflake'
OR CommandLine =~ '(?i)snowsql|snowflake.connector|account=.*\\.snowflakecomputing\\.com'
-- Locate Snowflake CLI config files (potential plaintext credential storage) and large CSV/JSON exports in user profiles
SELECT FullPath, Size, Mtime
FROM glob(globs=['C:/Users/*/.snowsql/config', 'C:/Users/*/.snowflake/*', '/home/*/.snowsql/config', 'C:/Users/*/Downloads/*.csv', 'C:/Users/*/Desktop/*.csv'])
WHERE Size > 10000000 OR FullPath =~ '(?i)snowsql|snowflake'
#!/bin/bash
# Snowflake tenant hardening & exposure audit — run with an ACCOUNTADMIN-equivalent session.
# Produces a point-in-time report of MFA gaps, network policy status, and anomalous logins.
SNOWSQL_CMD="snowsql -o output_format=csv -o header=true -o timing=false"
echo "=== [1] Users without MFA enforced ==="
$SNOWSQL_CMD -q "
SELECT name, login_name, type, has_mfa, disabled, last_success_login
FROM snowflake.account_usage.users
WHERE deleted_on IS NULL
AND disabled = FALSE
AND (has_mfa = FALSE OR has_mfa IS NULL)
AND type IN ('PERSON','LEGACY_SERVICE');"
echo "=== [2] Network policies (account & user level) ==="
$SNOWSQL_CMD -q "SHOW NETWORK POLICIES;"
$SNOWSQL_CMD -q "SELECT name FROM snowflake.account_usage.network_policies WHERE deleted_on IS NULL;"
echo "=== [3] Successful logins from non-browser clients in last 14 days ==="
$SNOWSQL_CMD -q "
SELECT user_name, client_ip, reported_client_type, first_authentication_factor, count(*) AS logins
FROM snowflake.account_usage.login_history
WHERE is_success = 'YES'
AND event_timestamp > DATEADD(day, -14, CURRENT_TIMESTAMP())
AND reported_client_type NOT IN ('Snowflake UI')
GROUP BY 1,2,3,4
ORDER BY logins DESC;"
echo "=== [4] COPY INTO stage exports in last 14 days ==="
$SNOWSQL_CMD -q "
SELECT user_name, role_name, query_text, rows_produced, execution_status, start_time
FROM snowflake.account_usage.query_history
WHERE start_time > DATEADD(day, -14, CURRENT_TIMESTAMP())
AND (query_text ILIKE '%COPY INTO @%' OR query_text ILIKE '%COPY INTO ''s3%'
OR query_text ILIKE '%COPY INTO ''azure%' OR query_text ILIKE '%COPY INTO ''gcs%')
ORDER BY rows_produced DESC;"
echo "=== [5] Enforce MFA + password policy baseline (review before executing) ==="
echo "-- ALTER ACCOUNT SET ENABLE_MANDATORY_MFA = TRUE; (if licensed / applicable)"
echo "-- CREATE OR REPLACE NETWORK POLICY corp_only ALLOWED_IP_LIST = ('x.x.x.x/32');"
echo "-- ALTER ACCOUNT SET NETWORK_POLICY = corp_only;"
echo "-- ALTER USER <svc_account> SET TYPE = SERVICE; -- disables password auth for service principals"
Remediation
Because there is no patch, remediation is entirely about identity, configuration, and third-party governance. Prioritize in this order:
1. Rotate everything that can send. Immediately rotate API keys and credentials for all customer engagement platforms (push, email, SMS, in-app). Revoke dormant keys. If your platform supports it, scope keys by environment and by action (draft vs. send), and require IP allowlists for the send API.
2. Enforce dual approval for outbound campaigns. A single set of credentials should never be able to message your entire customer base. Configure maker-checker workflows in your engagement platform, alert on campaigns created outside business hours or from unrecognized IPs, and cap audience size per API token.
3. Lock down Snowflake tenants. Enforce MFA on every user (including service accounts — migrate them to key-pair or OAuth authentication), apply account-level network policies restricting logins to known egress IPs/VPNs, disable password-only LEGACY_SERVICE accounts, and alert on COPY INTO exports over a row threshold. Snowflake's guidance on preventing unauthorized access from the 2024 campaign remains the operative baseline; follow their security best-practices documentation and your account team's advisories.
4. Hunt for infostealer exposure. Stolen credentials are the most common root cause. Search threat-intel feeds and stealer-log marketplaces (or your CTI provider) for corporate domains, and force password resets for any account appearing in logs. Check endpoints for stealer infections — a Snowflake session token or engagement-platform cookie on a compromised workstation is all an attacker needs.
5. Audit the third-party graph. Inventory every vendor with standing access to customer data or customer communication channels. Confirm contractual breach-notification SLAs, review their authentication requirements, and include engagement-platform abuse in your incident response playbooks — specifically: how do you stop a malicious campaign mid-flight, and who has authority to pull the kill switch?
6. Prepare the customer-trust response. ASOS's measured disclosure (confirming limited PII exposure, ruling out payment data and passwords) is the model. Pre-draft notification templates and regulator reporting timelines now — under GDPR and US state breach laws, the clock starts at discovery, not at certainty.
The strategic takeaway: attackers have learned that humiliating a brand through its own trusted channels is often more valuable than quietly selling the data. Your detection and IR scope must extend beyond the data layer to every system that can speak to your customers.
Related Resources
Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.