Three live AI-provider keys shipped as an “inbuilt” free tier in LeetMentor
The Firefox extension LeetMentor bundled active Google Gemini, Groq and OpenRouter API keys in plain text inside config.js, described in its own comments as “inbuilt API keys … intended for casual users.” Because a published extension ships as readable code, anyone can extract and spend against these keys — a representative case of the AI-extension shared-key anti-pattern.
The Firefox extension LeetMentor (version 1.1, distributed via addons.mozilla.org) shipped three live third-party AI API keys — a Google Gemini key, a Groq key and an OpenRouter key — hardcoded in plain text in config.js. All three authenticated successfully at scan time and are billed to the maintainer's own provider accounts.
Unlike an accidental leak, the keys were embedded deliberately: the file's own comments describe them as “inbuilt API keys for users who don't provide their own … rate-limited keys intended for casual users.” The intent — a free tier so casual users need not bring their own key — is reasonable; the delivery is not. A published browser extension is a ZIP of readable JavaScript. Any user can unpack it, read the keys, and use them from their own scripts, entirely outside the extension and its rate limits.
codelake detected the keys automatically within the scan pipeline (secret scanning cross-checked against live-credential validation), archived the extension, and notified the maintainer under responsible disclosure. This advisory is published as a study of the pattern, not as an accusation — LeetMentor is one clear instance of a mistake we observe across the current wave of AI-assistant extensions.
The maintainer's comment reflects a common misconception: that per-key rate limits contain the risk. They do not. Rate limits throttle legitimate users of the extension; they do nothing against an attacker who lifts the key and calls the provider directly. The practical consequences:
OpenRouter (sk-or-v1-…) is the most serious — it fronts every provider it routes to and spends real credit on the maintainer's account, so extraction can translate directly into money. Gemini and Groq keys can be drained for free compute, which exhausts the shared quota so the extension's own users are rate-limited out of the feature — and, if billing is enabled, incurs cost. In every case the key belongs to the maintainer, not to the person who extracts it.
The keys are exported from config.js as a plain object. The surrounding comments document the intent directly — which is what makes this a clean illustration of the anti-pattern rather than an isolated slip.
Each key was matched by a named provider signature and then validated as an active credential — the finding does not rest on entropy alone. Beyond the keys, static analysis of the extension flagged a broader capability surface: a read of browsing data (history/bookmarks/tabs) followed by an outbound request in popup.js, and dynamic code execution in content.js. For a coding-assistant extension these are plausibly functional (reading the active problem page, injecting UI), so they are reported here as capability, not as evidence of malicious intent — but they widen the blast radius should any component be compromised.
config.js containing the inbuilt keys.19:57 UTC
config.js and the extension is captured to the codelake archive.~20:00 UTC
20:21 UTC
13:47 UTC
Detected and validated by codelake Research · automated secret scanning · live-credential validation · static capability analysis · disclosed to the maintainer before publication.
Credential values are redacted and were never stored — codelake retains only the detection rule, file location and validation status. The archived extension is available to verified security researchers on request.