⚠ High Security Advisory LeetMentor · Firefox (AMO) · 1.1 Disclosed 2026-07-02 · 13:47 UTC
Identity revealed. The 30-day coordinated-disclosure window (maintainer/vendor notified 2026-07-02) has passed; the affected software is now named. codelake never stores raw secrets — only the detection rule, file:line and status are retained.
Advisory · CLR-2026-0849

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.

HighCredential ExposureAI / LLM KeysClient-Side SecretConfirmed · keys validated live
Summary

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.

Why “rate-limited” does not protect the keys

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.

Technical Analysis

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.

config.js · lines 1 – 9 ⚠ embedded live keys
1// Inbuilt API keys for users who don't provide their own
2// These are rate-limited keys intended for casual users
3// Users can add their own keys via Settings for higher limits
4 
5export const INBUILT_KEYS = {
6 GEMINI: "AIzaSy••••••••••••••••••••••••••••••••",
7 GROQ: "gsk_••••••••••••••••••••••••••••••••••••",
8 OPENROUTER: "sk-or-v1-••••••••••••••••••••••••••••••••"
9};

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.

Timeline
Extension listed on AMO
The Firefox extension LeetMentor 1.1 published on addons.mozilla.org with config.js containing the inbuilt keys.
2026-07-01
19:57 UTC
Automatic detection & archive
The scan pipeline flags three provider keys in config.js and the extension is captured to the codelake archive.
2026-07-01
~20:00 UTC
Live validation
All three keys confirmed as active credentials — Gemini, Groq and OpenRouter — not test fixtures.
2026-07-01
20:21 UTC
Advisory drafted
Consolidated disclosure prepared — all three keys in a single notice to the maintainer.
2026-07-02
13:47 UTC
Maintainer notified
Responsible-disclosure email sent to the maintainer's domain contact. A 30-day window to remediate begins.
2026-08-01
Public disclosure deadline
Identity revealed automatically after the 30-day window, whether or not the keys were rotated.
Indicators of Exposure
KEYAIzaSy•••••••••••••••••••••••••••••••• (Google Gemini — active, config.js:6)
KEYgsk_•••••••••••••••••••••••••••••••••••• (Groq — active, config.js:7)
KEYsk-or-v1-•••••••••••••••••••••••••••••••• (OpenRouter — active, config.js:8)
PKG[email protected] (Firefox / AMO) · leetmentor-1.1.xpi
SHA11e957d138cd53872d621fc46ba4aea689badb672e7407aca246cf12760cc841
Remediation
#ActionPriority
01 Revoke and rotate all three keys. Delete/regenerate the Gemini key (Google AI Studio / Cloud Console), the Groq key (GroqCloud console) and the OpenRouter key (OpenRouter → Keys). OpenRouter first — it can incur spend. Immediate
02 Move the free tier behind a proxy. Keep the keys server-side in a small backend that the extension calls; the key never ships in client code, and you can rate-limit and revoke per user. High
03 Check provider usage for the exposure window for unexpected spend or quota drain, especially on OpenRouter. High
04 Publish a clean version with the embedded keys removed; do not rely on obfuscation — a bundled key is still extractable. Medium

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.