Stanford University researchers scanned 10 million webpages and found 1,748 valid API credentials. The keys included AWS access tokens, Stripe payment credentials, GitHub tokens, and OpenAI keys scattered across roughly 10,000 pages. Affected organizations included a G-SIB bank, a drone firmware developer, government agencies, and critical infrastructure entities.
Exposed credentials had been publicly accessible for an average of 12 months. Some had been live for years.
The paper (arXiv:2603.12498), titled "Keys on Doormats," was submitted March 12, 2026. The authors are Nurullah Demir (Stanford, PhD candidate), Yash Vekaria (UC Davis), Georgios Smaragdakis (TU Delft and Stanford), and Zakir Durumeric (Stanford).
What we found were highly sensitive API credentials left publicly exposed on public webpages. These act as access tokens that authorize applications to interact with third-party services, granting direct access to critical infrastructure like cloud platforms and payment providers.
— Nurullah Demir, PhD candidate, Stanford University
The researchers used TruffleHog v3.90.8, an open-source secret scanner that identifies over 800 distinct secret types, to analyze the HTTP Archive dataset. The pipeline worked in three stages. TruffleHog scanned all HAR files in offline mode for credential patterns. The team then localized each detection to its location in the web resource. Finally, they validated each candidate against the actual service's API using non-destructive calls.
For AWS, validation used the GetCallerIdentity endpoint, which returns the account identifier without exposing or modifying sensitive data. Only credentials that passed live validation were counted. The team verified against 14 service providers, meaning 1,748 is a lower bound.
84% of exposed credentials appeared in JavaScript resources. HTML accounted for 8%, JSON for 7%.
Within JavaScript files, 62% of credential exposures appeared in bundles created by Webpack. The leak occurs not at the commit stage but at the build stage. A developer may correctly exclude secrets from source control, but the build pipeline injects environment variables into the Webpack bundle. That bundle is then served to every visitor as a static asset.
A 'Global Systemically Important Financial Institution' exposed its cloud credentials directly on its webpages. This gave direct access to multiple core cloud infrastructure services, including databases and key management systems.
— Nurullah Demir, PhD candidate, Stanford University
AWS credentials alone represented more than 16% of all verified exposures and appeared on over 4,693 websites. Cloud services (AWS, Cloudflare) and payment processors (Stripe, Razorpay) accounted for the majority. Email and communication services (SendGrid, Twilio) appeared frequently, with many originating from embedded third-party resources.
The drone firmware developer exposure is a supply chain vector. An attacker could have used those repository credentials to modify source code and push malicious firmware updates to production devices. The only prerequisite was reading a public webpage.
When we got feedback from the developers, we saw that a significant number of them were completely unaware of the exposures. What is perhaps most concerning is that our historical analysis showed these credentials often remain exposed for an average of 12 months, in some cases for years.
— Nurullah Demir, PhD candidate, Stanford University
After disclosure began, the number of exposed credentials declined by roughly half within two weeks. Demir stated that the actual number across the full web is "much higher" than what this study captured.
Modern JavaScript build tools (Webpack, Vite, esbuild, Rollup) replace references to process.env.API_KEY in source code with the actual value at build time. If a developer references a server-side secret in client-side code, the tool embeds it in the output bundle. The .env file never appears in the repository. But the secret appears in the compiled output deployed to production and cached by CDNs.
API credentials bypass interactive authentication entirely. A stolen password requires a login flow and may be blocked by MFA. A stolen API key provides direct automated access to cloud infrastructure, payment processing, or code repositories. The blast radius of a single exposed AWS access key can include S3 buckets, EC2 instances, RDS databases, Secrets Manager, and IAM configuration.
Previous credential exposure studies focused on GitHub repositories and cloud storage. The Stanford paper is among the first to scan what browsers actually receive rather than what developers commit to version control.
Truffle Security, the company behind TruffleHog, previously launched Forager, a tool that scans the public web for live API keys. Forager found that 0.1% of all GitHub pushes contain live credentials, with 90.9% in personal repositories. At NahamCon, Truffle Security's CEO leaked a canary AWS token in a zero-star repository. Within 10 minutes, someone attempted to authenticate with it.
Scan production build output, not just source code. Running trufflehog filesystem ./dist --only-verified against the build directory will detect secrets embedded during compilation. Audit Webpack or Vite configuration for process.env.* references in client-side code. Use naming conventions that enforce the boundary (NEXT_PUBLIC_* in Next.js, VITE_* in Vite). Rotate any credential that has appeared on a public webpage.
Have a story? Become a contributor.
We work with independent researchers and cybersecurity professionals. Send us a tip or submit your article for editorial review.