Eighteen months in, we’ve completed 38 engagements. They span fintechs, fleet- management SaaS, two robotics companies, and a healthtech firm we can’t name. Different stacks, different teams, very different threat models.
And yet — the same six findings appear in roughly the same order, every time.
Treat this list as a pre-emptive remediation roadmap. If you can knock these out before our next visit (or, ideally, before someone else’s first visit), the rest of the engagement is materially more useful.
The list
| # | Finding | Severity | Time to fix | Notes |
|---|---|---|---|---|
| 01 | Long-lived API keys in CI | CRITICAL | 4h | Rotate to OIDC |
| 02 | Public S3 / blob containers | CRITICAL | 2h | Audit, lock down |
| 03 | Stale admin accounts | MEDIUM | 6h | Disable inactive 90d+ |
| 04 | Missing 2FA on SaaS admin | MEDIUM | 3h | Enforce in IdP |
| 05 | Forgotten staging subdomains | MEDIUM | 1d | DNS sweep + decommission |
| 06 | Verbose error pages in prod | LOW | 2h | Stack traces leak path info |
Roughly three engineering days of work, total. The probability that one of them is currently true for you, right now, is empirically around 91%.
Why these six, in this order
01 · Long-lived API keys in CI
This is finding #1 because it’s the cheapest to find and the highest-impact
when it works. A GitHub Actions log with AWS_SECRET_ACCESS_KEY printed
during a terraform plan is a full account takeover.
Fix: migrate to OIDC federation. GitHub, GitLab, and CircleCI all support short-lived tokens issued at workflow start.
02 · Public storage buckets
We run a small script that enumerates bucket names from your domain prefix and tests each for anonymous read. We have never run an engagement where this returned zero results.
The fix is one-line — apply a Block public access policy at the account
level — but it requires an inventory pass to confirm no legitimate consumer
is broken by it.
03 · Stale admin accounts
Every company we’ve tested has between three and twenty admin accounts for former employees, former contractors, or former vendors. Most are protected only by a password the user reused on three other services.
The fix is a 90-day inactivity sweep across every system that authenticates people, plus enforced 2FA on every account that survives.
04 · Missing 2FA on SaaS admin
Related to #03 but worth its own bullet because the surface is broader: it’s not just your admin console. It’s GitHub, GitLab, AWS, GCP, Datadog, Sentry, Stripe, Notion, and twenty others.
If your IdP supports it, enforce 2FA on the admin role globally. Don’t ask, don’t notify, don’t email a “deadline.” The exemption list goes to one.
05 · Forgotten staging subdomains
This is the subtle one. staging-old.example.com was decommissioned, but
the DNS record still points at a Heroku app from 2022 that’s now available
for anyone to claim.
The script in our recon-tools repo will enumerate yours from certificate-transparency logs — run it on yourself before someone else does.
06 · Verbose error pages in production
The lowest-severity item on the list but worth the two hours. Stack traces on 500 responses leak file paths, dependency versions, and (in Django’s default error page) sometimes environment variables.
Turn DEBUG = False on. The error page should say “something went wrong.”
What this list isn’t
It is not defense-in-depth. It is not a substitute for a real threat model. It will not stop a determined adversary.
It will, statistically, catch the opportunistic 80% — which is who is going to ruin your week.
One more thing
If you’ve fixed all six and want a real engagement, we should talk.
Found this useful? Send it to someone who'd benefit, or email us a question.