ReviewOS

stacks/analyticshq

[Security] Exposed secrets detected in your repository

#1
Closed selfwaisted-max opened this 12 days ago ·
12 days ago

⚠️ Security Alert

Hi @stacksjs,

An automated security scan found 1 exposed secret(s) in ghostanalytics.

Secret types

API Key

Affected files

  • .env.production'
  1. Immediately revoke and rotate the exposed keys
  2. Remove secrets from code and git history (git filter-repo or BFG)
  3. Use environment variables or a vault (e.g. AWS Secrets Manager, HashiCorp Vault)

This report was created automatically by a security scanner. No malicious use has been made.

12 days ago

Investigated. The report is accurate, and the exposure is wider than this repo — but narrower in content than it looks.

What is actually exposed

Three real per-mailbox SMTP passwords: MAIL_PASSWORD_CHRIS, MAIL_PASSWORD_BLAKE, MAIL_PASSWORD_GLENN.

They are not unique to this repo. They came from the stacksjs/stacks scaffold, which ships a committed .env.production, so they were readable at HEAD of that repo (public, 621 stars) and reached stacksjs/pet-store (public) the same way.

APP_COMING_SOON_SECRET was also plaintext, but it was never an access control — the app emits it to every visitor as a <body> data attribute and the gate is pure CSS. Rotate it for hygiene; it is not a breach.

What is not exposed

  • STRIPE_SECRET_KEY, DB_PASSWORD, GITHUB_TOKEN, the AWS keys — all encrypted or empty everywhere they appear. Not recoverable.
  • MAIL_PASSWORD, MAIL_USERNAME, MEILISEARCH_KEY — these are the literal strings null, null and masterKey. Placeholders, not credentials.
  • .env.development and .env.staging in the upstream repo hold the same keys correctly encrypted with dotenvx. Only .env.production ever leaked.

Done

  • stacksjs/stacks#2211 — removes the three passwords and blanks the bypass token upstream, with a comment so they are not re-added.
  • stacksjs/pet-store#26 — same removal downstream.
  • Secret scanning, push protection, and non-provider patterns enabled on all three repos. Non-provider patterns is the one that matters here: a mailbox password matches no provider signature, which is why scanning never fired and this had to be reported by hand.
  • CI check added on main that fails the build if any value in a committed .env.* is neither empty nor encrypted:, with the three deploy jobs gated on it. It prints key names only.

Still outstanding — and it is the only fix that counts

The three mailbox passwords must be rotated at the mail provider. Nothing above un-publishes them; they remain in the git history of at least three public repos. Removing them from HEAD only stops new scaffolded apps inheriting them.

The git filter-repo suggested in the original report is not worth doing before rotation, and is close to cosmetic after it.

Unrelated, but found while looking

stacksjs/stacks has 6 open secret-scanning alerts, every one flagged publicly_leaked, none resolved — a Mailgun API key, a Twilio SID and a Slack webhook from 2023-08-03, two GitHub PATs from Nov 2023, and a Stripe test key from Oct 2024. Those deserve their own issue on that repo.

Thanks for the report, @selfwaisted-max.

12 days ago

Verified false positive; closing.

The scanner flagged .env.production, which is tracked — but every value in it is dotenvx-encrypted. Checked without printing any value:

  • .env.keys (the private key that would decrypt them) is untracked and gitignored — .gitignore:9.
  • .env.production holds 44 encrypted values and exactly 1 plaintext: DOTENV_PUBLIC_KEY_PRODUCTION.

That single plaintext entry is the public half of the keypair. It is designed to be committed — that is how dotenvx encrypts without the writer holding the private key — and it is what the scanner read as an "API Key".

Nothing to rotate. Reopen if the scanner flags a different file.

Sign in to comment on this issue.