{"id":51118721,"url":"https://github.com/perufitlife/dotenv-exposure-check","last_synced_at":"2026-06-25T00:01:25.390Z","repository":{"id":366362835,"uuid":"1275993965","full_name":"Perufitlife/dotenv-exposure-check","owner":"Perufitlife","description":"Zero-dep CLI that probes a live URL for accidentally-served secret artifacts (.env, .git/, .js.map source maps, .DS_Store, backups) and CONFIRMS each hit by fetching the bytes.","archived":false,"fork":false,"pushed_at":"2026-06-21T12:50:11.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-21T14:40:11.483Z","etag":null,"topics":["devsecops","dotenv","env","exposure-scanner","secret-scanning","secrets-detection","security","security-audit","security-tools","sourcemap"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Perufitlife.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-21T12:06:25.000Z","updated_at":"2026-06-21T12:50:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Perufitlife/dotenv-exposure-check","commit_stats":null,"previous_names":["perufitlife/dotenv-exposure-check"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Perufitlife/dotenv-exposure-check","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fdotenv-exposure-check","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fdotenv-exposure-check/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fdotenv-exposure-check/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fdotenv-exposure-check/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Perufitlife","download_url":"https://codeload.github.com/Perufitlife/dotenv-exposure-check/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Perufitlife%2Fdotenv-exposure-check/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34753781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devsecops","dotenv","env","exposure-scanner","secret-scanning","secrets-detection","security","security-audit","security-tools","sourcemap"],"created_at":"2026-06-25T00:01:24.243Z","updated_at":"2026-06-25T00:01:25.376Z","avatar_url":"https://github.com/Perufitlife.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dotenv-exposure-check\n\n\u003e Probe any **live URL** for the secret artifacts that get served by accident — `.env`, `.env.production`, the `.git/` directory, production source maps (`.js.map`), `.DS_Store`, and backup/database dumps — and **prove each hit by fetching the bytes** and showing the real credentials, remote URLs, and source paths inside. Other scanners read your repo; this checks what your *server* is actually handing to strangers.\n\n\u003e ⚡ **Run it in one line, no install, no token:**\n\u003e ```bash\n\u003e npx dotenv-exposure-check --url https://your-app.example.com\n\u003e ```\n\n\u003e 🤝 **Want it done for you?** [Fixed-scope audit — $99 / 24h](https://buy.stripe.com/3cIeVdgikfj47yx9LkcAo0m): I verify each exposure live, help you rotate the leaked credentials, and send a written remediation report.\n\n[![npm](https://img.shields.io/npm/v/dotenv-exposure-check?color=red)](https://www.npmjs.com/package/dotenv-exposure-check) [![downloads](https://img.shields.io/npm/dw/dotenv-exposure-check)](https://www.npmjs.com/package/dotenv-exposure-check) ![license](https://img.shields.io/badge/license-MIT-green) ![node](https://img.shields.io/badge/node-%3E%3D18-blue) ![deps](https://img.shields.io/badge/dependencies-0-brightgreen)\n\n```\n$ npx dotenv-exposure-check --url https://app.example.com\n2 critical, 1 high, 1 medium — 4 CONFIRMED by fetching the bytes\n  CRITICAL  /.env            5 vars readable — secret keys: DATABASE_URL, STRIPE_SECRET_KEY, JWT_SECRET\n  CRITICAL  /.git/config     repo cloneable — remote https://\u003ccredentials-redacted\u003e@github.com/acme/app.git\n  HIGH      /main.js.map     12 source files mapped (original source embedded)\n  MEDIUM    /.DS_Store       directory listing leaked\n```\n\n## Why this exists\n\nServing a secret file is the single highest-yield mistake on the web, and it\nhappens constantly: researchers catalogued **12M+ exposed `.env` files** in the\nwild, and Palo Alto Unit 42 documented an extortion campaign that **scanned 230M\ntargets and harvested 90,000+ secret variables** from misconfigured `.env`\nendpoints. Source maps are just as bad — even Claude Code shipped a production\n`.js.map` leak in 2026 — and a web-readable `.git/` folder lets anyone clone your\nentire source, remote token included.\n\nThe hard part is *confirmation*. Most single-page apps return `200 OK` with\n`index.html` for **every** path, so \"got a 200 on `/.env`\" means nothing.\n`dotenv-exposure-check` fetches each candidate and **inspects the actual bytes**:\nan `.env` hit must contain real `KEY=VALUE` assignments, a source map must be\nvalid sourcemap JSON, a `.DS_Store` must carry the `Bud1` magic, a backup must\nhave a real archive/dump signature. You triage facts, not 200s.\n\n## What it checks\n\n| Check | Severity | How it's confirmed |\n|---|---|---|\n| `.env` / `.env.production` / `.env.local` … served | critical | body parsed for `KEY=VALUE` lines; secret-looking keys (DB/API/JWT/Stripe/AWS) flagged |\n| Exposed `.git/` directory (repo cloneable) | critical | `/.git/config` + `/.git/HEAD` validated as git stanzas; embedded remote credentials detected and redacted |\n| Production source map (`.js.map`) exposed | high | parsed as sourcemap JSON (`version` + `mappings`); counts mapped sources, flags embedded original source |\n| Backup / database dump downloadable | high | archive (`zip`/`gzip`) or SQL-dump signature in the bytes |\n| `.DS_Store` directory listing | medium | `Bud1` binary magic at offset 4 |\n\nSPA catch-all (`200` + `index.html` for everything) is explicitly rejected, so\nthe tool does not false-positive on modern frontends.\n\n## Usage\n\n```bash\n# Probe a live site (tries the common filenames for each artifact)\nnpx dotenv-exposure-check --url https://app.example.com\n\n# Restrict to specific candidate paths\nnpx dotenv-exposure-check --url https://app.example.com --paths .env,.env.production\n\n# Write a shareable HTML report\nnpx dotenv-exposure-check --url https://app.example.com --html report.html\n\n# Dry run: list what would be checked, send no requests\nnpx dotenv-exposure-check --url https://app.example.com --no-probe\n```\n\nOutput is JSON on stdout (pipe it into CI) and a one-line summary on stderr.\nExit is non-zero only on usage errors — gate your pipeline on the JSON `summary`.\n\n## Install (optional)\n\n```bash\nnpm i -g dotenv-exposure-check\ndotenv-exposure-check --url https://app.example.com\n```\n\nZero dependencies. Read-only and keyless — every request goes straight from the\ntool to the target you name; nothing is stored, modified, or sent anywhere else.\n**Only scan systems you own or are authorized to test.**\n\n## Sister tools\n\nSame active-probe philosophy across the stack, all MIT:\n\n[supabase-security](https://github.com/Perufitlife/supabase-security-skill) ·\n[pocketbase-security](https://github.com/Perufitlife/pocketbase-security-skill) ·\n[firebase-security](https://github.com/Perufitlife/firebase-security-skill) ·\n[appwrite-security](https://github.com/Perufitlife/appwrite-security-skill) ·\n[nhost-security](https://github.com/Perufitlife/nhost-security-skill) ·\n[strapi-security](https://github.com/Perufitlife/strapi-security) ·\n[directus-security](https://github.com/Perufitlife/directus-security) ·\n[aws-s3-security](https://github.com/Perufitlife/aws-s3-security) ·\n[stripe-webhook-security](https://github.com/Perufitlife/stripe-webhook-security) ·\n[github-actions-security](https://github.com/Perufitlife/github-actions-security) ·\n[web-exposure-mcp](https://github.com/Perufitlife/web-exposure-mcp)\n\n## License\n\nMIT © [Renzo Madueno](https://github.com/Perufitlife)\n\n---\n\n📚 Part of [**Awesome Backend Security Auditors**](https://github.com/Perufitlife/awesome-backend-security) — the full collection of keyless active-probe auditors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperufitlife%2Fdotenv-exposure-check","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperufitlife%2Fdotenv-exposure-check","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperufitlife%2Fdotenv-exposure-check/lists"}