Cafiyn Pulse
← Startup Signals
6 min readUpdated 2026-09-17Issue 3

1.8 million Android apps were scanned for hardcoded keys. Here is how to check yours.

Finding secrets in shipped apps is now a cheap, automated pipeline. Anything compiled into an APK, an IPA or a JavaScript bundle should be treated as already published.

ByKarthik KumarCafiyn Innovations
At a glance
Apps scanned
1.8 million Android APKs, decompiled
Tooling
TruffleHog, on 10 AWS EC2 workers
Outcome
Supplied initial access for most confirmed breaches tied to the operator
Report period
December 2025 to August 2026
Related
Mass scanning of exposed Vite dev servers, August 2026

What the report describes

Anthropic published its September threat intelligence report on 10 September, covering December 2025 to August 2026. One section concerns suspected affiliates of ShinyHunters. It describes an operator who ran a pipeline on ten AWS EC2 workers that downloaded 1.8 million distinct Android application packages, decompiled them, and scanned the result with TruffleHog, an open-source secret scanner.

Verified findings were routed in real time into a Telegram group organised into more than 100 source types, and a parallel harvester collected GitHub personal access tokens. Anthropic says those two pipelines supplied the initial-access credentials for most of the confirmed breaches tied to the operator. It says the group used Claude to speed up parts of its operation, and that it banned the associated accounts.

The detail worth sitting with is not the scale, it is the economics. Ten rented machines and a free tool processed a meaningful fraction of the Play Store. Looking inside your shipped app is no longer something an attacker does to you in particular. It is something that happens to everyone, continuously, as a background process.

Why a shipped bundle is public

An Android APK is a zip archive. An iOS IPA is too. A web app's JavaScript is delivered to every visitor in plain text. Minification and obfuscation change how the code reads, not what strings it contains, and a secret scanner looks for strings. If a credential is in the build, it is in the hands of anyone who downloads the build.

The common failure is not carelessness about the repository. Many teams scan their repo and are clean there, because the secret lives in a build-time environment variable. The build then inlines that variable into the bundle. The repo scan passes and the shipped artefact leaks.

The secrets that matter most

Not every key in a client is a problem. Some are designed to be public and are scoped accordingly. The ones below are not, and each has a standard fix.

  • Supabase service_role key: bypasses row level security entirely. The client should only ever hold the anon key, with access enforced by RLS policies.
  • Stripe secret key (sk_live_): can move money and read customer data. The client gets the publishable key; anything needing the secret key runs on your server.
  • LLM provider API keys: turn into someone else's compute bill within hours. Proxy model calls through your own backend, with per-user rate limits.
  • Cloud credentials (AWS, GCP, Azure): usually the broadest blast radius of all. There is no safe way to ship these to a client.
  • Third-party admin or write tokens for email, SMS, analytics or CMS providers, which tend to be granted more scope than the feature needs.

Scanning what you actually ship

The fix is to scan the build output, not only the source. Run your secret scanner after the build step, against the directory or archive you are about to publish, and fail the pipeline on a finding.

The same logic applies to development servers. F5 Labs reported a sharp rise in scanning of internet-reachable Vite dev servers in August 2026, using CVE-2026-39364 to read .env files and cloud credentials. Patch Vite to 7.3.2, 8.0.5 or the equivalent fixed release, and never bind a dev server to a public interface on a cloud VM, tunnel or staging box.

  • Add a secret scan that runs on build output: the web dist folder, the APK or AAB, the IPA
  • Fail the build on any high-confidence finding, rather than reporting and continuing
  • For anything found, rotate first and then remove it: removal alone does not un-publish a key that already shipped
  • Check old releases too, since earlier versions are still downloadable and still contain whatever they contained

What to do

  1. 1Run a secret scanner against your most recent production build output today, not just the repository.
  2. 2Search specifically for Supabase service_role, Stripe sk_live_, LLM provider keys and cloud credentials.
  3. 3Rotate anything you find before removing it. A key that shipped is compromised whether or not it has been used.
  4. 4Move every call that needs a secret server-side, and use scoped, publishable keys in the client.
  5. 5Patch Vite and confirm no dev server is reachable from the internet.

Common questions

Can someone really extract API keys from my mobile app?

Yes. APKs and IPAs are archives that can be unpacked and decompiled, and a secret scanner finds credential-shaped strings regardless of obfuscation. Anthropic's September 2026 threat report describes one operator doing this to 1.8 million Android apps.

Is the Supabase anon key safe to ship in a client?

Yes, when row level security is enabled and your policies are correct: the anon key is designed to be public and access is enforced by RLS. The service_role key is not: it bypasses RLS and must never reach a client.

Is it safe to ship a Stripe publishable key?

Yes, the publishable key is designed for client use. The secret key, which starts with sk_live_ or sk_test_, must stay on your server.

I found a key in an old build. Is removing it enough?

No. Rotate it first. Old releases remain downloadable, so a key that shipped should be treated as compromised whether or not you can see it being used.

Sources

Read against the primary documentation rather than secondary coverage. Where a figure comes from a provider's own docs, it is quoted as published on 2026-09-17.

Related

More from Signals

OpenAI's Agents API will hold your agent state. What breaks if you ever need to leave.
Two major providers moved into the agent state layer in the same week. A managed harness is a real shortcut, as long as you keep a copy of what it holds.
Meta's Muse agent can now check out at your store. What merchants should change.
Agent purchases are arriving through wallets and single-use cards, not through merchants adopting a new protocol. Many merchants will receive them without choosing to.
What Brevo's SSO incident teaches about multi-tenant SAML and hijacked sending accounts.
One incident, two lessons: why email authentication did not help, and the tenant-scoping mistake anyone shipping SSO can make.
Cloudflare now sorts bots into Search, Training and Agent. What it means for your site and your agent.
The same change lands on two audiences. Site owners can now accidentally block search; agent builders will find more doors closed.
OpenAI has published seven shutdown dates. Here is the calendar.
Seven dates between 23 October and 26 February. Every one announced months ahead, in public. The failure mode is never the notice.
Nvidia bought Hugging Face. Your open-weight fallback is now a vendor relationship.
The commitments say nothing breaks. The structural change is that "we can always self-host" is now a dependency on one vendor rather than on a neutral commons.
The Videos API goes away on 24 September and OpenAI names nothing to move to.
Every other deprecation on OpenAI's page offers a migration target. This one does not, which makes it a different kind of problem.
Whisper shuts down on 26 February. The risk is not the deadline.
Five months is a generous window. Whisper is also typically wired into a background job that fails into a queue rather than into a user's face.
The Assistants API is gone. Your app may not have told you yet.
It shut down on 26 August 2026. The replacement is not a drop-in, and the most common migration mistake changes your model's behaviour without throwing an error.
One Copilot code review costs 13 requests. Here is the rest of the maths.
Copilot now bills on usage rather than seats. The headline change is simple. The multipliers underneath it are where teams get surprised.
Row-level security is on by default now. That is not the same as being protected.
Lovable fixed the default. The gap that actually leaks data was never the default, it was the policy, and no platform can write that for you.
Your model comparison is measuring the wrong number.
Every price list is per token. Your bill is per finished piece of work. Those two numbers can rank models in opposite orders.
An agent with production log access is a new identity. Treat it like one.
Always-on agents that read production logs are arriving fast. The access-control question they raise is old and well understood, which is the good news.

Open the tool.

Ten production categories, three minutes, and a ranked list of what to fix first.

Check your own stack