Apify breach: compromised credential exposed customer accounts, 2FA recovery codes and sign-in tokens
SockAnalyst · Security+ certified analyst.
What happened
Apify says an unauthorized third party got into parts of its internal systems on November 9 and 10, 2026, using a compromised credential to obtain a number of account credentials and access related Apify accounts. Apify detected the activity on November 11 at 12:13 UTC, cut off access, rotated critical internal secrets, revoked some OAuth integrations (including GitHub) as a precaution, and notified authorities. On November 12 it said it had emailed customers whose personal information or stored data was accessed; it has not said how many. A customer notice shared publicly and reported by SecurityWeek lists names, emails, billing details, account activity, IP addresses, salted password hashes, 2FA recovery codes and phone numbers, and Google/GitHub sign-in tokens; card data was limited to cardholder name, expiry and last four digits. BleepingComputer saw notices saying affected API tokens and Apify Proxy passwords were rotated and telling users to reset 2FA. Apify now stores API tokens only as hashes and promised a post-mortem with root cause within a week of its Nov 13 update.
Who's affected
Apify customers who received an incident email, and any organization whose scrapers, Actors or integrations use Apify API tokens, Apify Proxy passwords, or GitHub/Google OAuth connections to Apify.
✅ Fix / patch
- If you got Apify's email, follow it: reset 2FA in the Apify Console and treat the old recovery codes as burned.
- Rotate any Apify API token or Proxy password still stored in your CI, secrets manager or code, even if Apify says it rotated affected ones, and update the consumers.
- Reconnect GitHub for Actors built from private repos (Actor > Change provider > GitHub > authorize, once per account and per org), and review the Apify OAuth app's access in GitHub and Google admin consoles.
- Set Console > Settings > General resource access to Restricted so storages can't be read by anyone who knows a storage ID, and warn staff about Apify-themed phishing (Apify says it never asks for passwords, 2FA codes or payment details).
🔎 Quick hunt check
No IOCs published. Apify has not released attacker IPs, domains or the intrusion method, and promises a post-mortem. Hunt on your side of the trust relationship: Apify OAuth app activity in GitHub audit logs (repo clones or token use since Nov 9), Entra/Google sign-ins or consents tied to Apify, and API traffic to api.apify.com from hosts that never run scrapers. The queries assume GitHub audit logs and proxy/firewall logs are in your SIEM.
MITRE ATT&CK: T1078, T1528, T1199
IOCs
No IOCs (IPs, domains or hashes) published by the sources yet.
Hunt queries
Starting points built only from published indicators. Field names vary; tune before use.
(index=github OR sourcetype=github:audit OR sourcetype="github:enterprise:audit") earliest=11/09/2026:00:00:00
("Apify" OR "apify") (action=oauth_* OR action=git.clone OR action=repo.* OR action=integration_installation.*)
| stats count min(_time) as first_seen max(_time) as last_seen values(action) as actions values(repo) as repos by actor, org
| append [ search (index=proxy OR index=network OR index=firewall) earliest=-14d (dest_host="api.apify.com" OR url="*api.apify.com*" OR dest_host="*.apify.com")
| stats count min(_time) as first_seen max(_time) as last_seen values(user) as users by src_ip, dest_host ]
| sort - count
// Apify breach Nov 9-10 2026: Apify OAuth app activity in GitHub plus which internal hosts talk to the Apify APIlet since = datetime(2026-11-09);
let OAuth = AuditLogs
| where TimeGenerated >= since
| where OperationName has_any ("Consent to application", "Add service principal", "Add OAuth2PermissionGrant")
| where tostring(TargetResources) has "Apify"
| project TimeGenerated, Source="EntraAudit", Actor=tostring(InitiatedBy.user.userPrincipalName), Detail=OperationName;
let SignIns = SigninLogs
| where TimeGenerated >= since
| where AppDisplayName has "Apify"
| project TimeGenerated, Source="SignIn", Actor=UserPrincipalName, Detail=strcat(IPAddress, " ", tostring(LocationDetails.countryOrRegion), " result=", ResultType);
let Net = CommonSecurityLog
| where TimeGenerated >= since
| where DestinationHostName endswith "apify.com" or RequestURL has "api.apify.com"
| project TimeGenerated, Source="Proxy", Actor=SourceIP, Detail=strcat(DestinationHostName, " ", RequestURL);
union OAuth, SignIns, Net
| summarize Count=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Details=make_set(Detail, 25) by Source, Actor
| order by Count desc
// Apify breach Nov 9-10 2026: Apify consents, sign-ins and API traffic since the intrusion window⏱ CISA deadline
Not in CISA KEV as of Nov 14, 2026.
Sources
- Apify Status: security incident updates (Nov 11-13, 2026)
- SecurityWeek: Apify Confirms Customer Data Accessed in Cyberattack
- BleepingComputer: Apify rotates API tokens, prompts 2FA resets after breach
Primary source note: Apify's official statement is its status page incident updates (status.apify.com); it has published no blog post or advisory yet. Exposed data types beyond 'personal information' and 'stored data' come from customer notices reported by SecurityWeek and BleepingComputer.
Related playbooks
- Mirae Asset Securities hacked twice in two days: 3,800 customer account numbers and 35,255 staff records leaked · Data breach · 2026-11-07
- Iris Ohyama's Iris Plaza breach: about 7.7 million people's data may be exposed via an external cloud service · Data breach · 2026-11-09
- Binance hot wallet theft (~$6.3B): losses covered, withdrawals resuming in phases · Breach · 2026-10-29
Get the Weekly KEV & Hunt Pack free — plus the daily SOC brief.
Weekly email; daily brief on the website.
Subscribe free
SockAnalyst