Skip to content

About

Runtime leak detector for modern web apps - finds exposed API keys, validates BaaS misconfigurations (Supabase/Firebase RLS), and catches secrets in JS bundles. Chrome extension + CLI.

Topics

Resources

Contributing

Security policy

Stars

276 stars

Watchers

1 watching

Forks

Latest commit

 

History

258 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KeyLeak Detector

PyPI GitHub License GitHub Action Chrome Extension Python

KeyLeak finds exposed credentials in browser traffic, local projects, build artifacts, and supported deployment archives. It checks selected backend-as-a- service configurations and returns redacted evidence with remediation guidance.

Install

The KeyLeak CLI requires Python 3.12 or newer. The static browser app runs without a Python installation on the visitor's device.

python -m pip install keyleak-detector

Or run without a permanent install:

uvx keyleak-detector --help

Quick start

Scan the current project before shipping:

keyleak local . --launch-profile launch-gate --fail-on high

Scan a web app you own or are authorized to test:

keyleak browser-scan https://your-owned-app.example --html > report.html

Scan an authorized site and its pages:

keyleak site-scan your-owned-domain.example \
  --depth 3 --max-pages 100 --max-subdomains 25 --baas-validate --html \
  > site-report.html

Use --json, --sarif, --markdown, or --html for machine-readable or shareable reports. See the agent scan runbook for setup and triage examples.

Choose a scan

  • PHP patch assessment: keyleak php-check URL --authorized checks ordinary response headers for the October 2026 PHP advisories. The local web bridge includes a URL form at /php-check. Hidden versions remain unknown; a patched banner does not prove a site is safe. The public PHP checker offers URL assessment and a browser-side version comparison.
  • Incident inputs: keyleak incident-check . checks selected manifests for compromised dependencies and outdated trust packages. Add --ca-bundle FILE for fingerprint checks or --railway for operator-requested recovery guidance. See incident checks and limits.
  • Local project: keyleak local . scans supported configuration, CI, Docker, MCP, source-map, and log files. Source files in node_modules and root dist/ are opt-in.
  • Binary release: add --scan-binaries to scan printable strings in recognized native files. Use keyleak archive release.zip --scan-binaries for ZIP/tar archives, including APK/IPA ZIP containers.
  • Web app: keyleak browser-scan URL scans one authorized target; keyleak site-scan DOMAIN discovers and crawls an authorized site.
  • Coordinated audit: keyleak audit --help describes the local, archive, and authorized network phases. Active network scans require explicit scope and attestation.

Audit writes redacted artifacts under .keyleak/audits/; artifact_dir is reported as an absolute path.

Advanced coverage limits, source scanning options, archive behavior, and examples are in scanner workflows and the binary artifact guide.

Local coverage options

Local scans cover configuration and infrastructure files such as .env, MCP, CI, Docker, source maps, and logs. Add source trees or release artifacts explicitly:

keyleak local . --scan-node-modules --json
keyleak local . --scan-dist --json
keyleak local . --scan-binaries --sarif
keyleak archive release.zip --scan-binaries --out release-report.json

--scan-node-modules checks JavaScript and TypeScript source; --scan-dist includes root dist/ build output. --scan-binaries checks printable strings in supported executables and binary members of ZIP/tar archives, with bounded common decoding and nested archive traversal. APK and IPA files are ZIP containers; DEX and mobile resource semantics remain unsupported. The scanner does not execute artifacts; encrypted and runtime-assembled secrets can be missed. Limits and unsupported scope are reported as incomplete coverage, never as a clean result. See the binary guide for supported formats, caps, and output examples.

Full site scans can use crt.sh, DNS, and installed subfinder / amass for subdomain discovery. They do not install missing tools by default. Operators can explicitly opt in with --auto-install; --no-auto-install remains supported. KEYLEAK_NO_AUTO_INSTALL=1 or KEYLEAK_MANAGED_INSTALL=1 vetoes installation even with explicit consent. keyleak doctor reports available discovery tools. See distribution readiness for the migration note and package-manager contract.

Use KeyLeak from an agent

Discover supported checks and their limits without starting a scan:

keyleak capabilities --json
keyleak local . --include agent-assets --packs leak --json

The second command checks skill instructions, agent rules, MCP configuration and common scripts/config files under agent directories for credential patterns. It does not execute those files or certify prompt-injection resistance.

Available skills: audit planning, local review, agent assets, and report triage. Review and copy a selected skill directory into your agent host's supported skills directory. These skills require KeyLeak on PATH and are distributed through the repository, not automatically installed by pip.

See the flow audit and ecosystem comparison for implementation evidence, positioning, validation limits and follow-up work.

Python secret serialization review

Opt into static source checks for credentials on Python dataclasses, attrs classes, Pydantic models, and class-style NamedTuple definitions:

keyleak local . --include serialization --packs leak --json

Inspired by Sentry's secret serialization review guidance. The check does not import or execute scanned code. It reports unprotected generated holders as medium review leads, and direct same-file exposing serializer uses as high leads. repr=False does not protect asdict; Pydantic dump exclusion does not protect repr. Raw vars, __dict__, and pickle paths bypass field flags and wrappers. Evidence includes field names and line numbers without copying source values. Optional Pydantic secret wrappers retain their masking. The exact metadata fields token_ttl: int, password_min_length: int, and cookie_secure: bool are excluded; numeric token and password fields remain in scope. Structural fingerprints support allowlists when KEYLEAK_FINDING_FINGERPRINT_KEY is configured.

This is a bounded Python source review, not proof of runtime disclosure. It resolves module-level holders, import aliases, direct constructor assignments, and typed function parameters. It checks explicit repr/dump/raw serializers, object formatting, and logging arguments. Partial exclusions require a traced unblocked path. Custom serializers, inherited/imported holders, custom redaction, conditional exclusions, comprehensions, cross-file/interprocedural flows, and JavaScript/TypeScript need manual review. Known test, fixture, example, dependency, build, and generated protobuf paths relative to the scan root are excluded. Existing file limits apply, plus 100,000 AST nodes and 1,000 findings per Python file. Parsing/analysis limits or no eligible Python sources make coverage incomplete; findings collected before a limit are retained. This check is opt-in and has no browser or extension bundle counterpart.

Findings and safe use

Reports include a verdict, severity, confidence, source, evidence, remediation, and a re-test command. Normalized reports redact credential values by default. Binary findings include a zero-based byte offset and omit surrounding string snippets so nearby credentials cannot leak through context.

Scans are bounded. If a file, archive, or scan limit is reached, earlier findings remain in the report and coverage is marked incomplete. Exit code 0 means the selected threshold passed with complete coverage; 1 means the command failed; 2 means the threshold was reached or coverage was incomplete.

Use KeyLeak only on systems you own or have permission to test. Authenticated scans should use throwaway credentials, for example:

keyleak scan https://your-staging-app.example \
  --profile authenticated --bearer "$THROWAWAY_TOKEN"

KeyLeak does not upload reports to a hosted service. Values are redacted in normalized reports by default. A proxy can see the scan traffic routed through it, so use a trusted local proxy rather than an unknown public service. Read the security model before scanning sensitive targets.

Read the result

KeyLeak retains the machine statuses SAFE_TO_SHIP, REVIEW, and BLOCK_SHIP. Local zero-finding reports say No findings in selected checks and include coverage, inventory, extraction limits, and a retest command preserving scan options. Archive envelopes bind the report and input digests; HMAC authentication requires KEYLEAK_COC_KEY. Use the evidence, confidence, remediation, and re-test command to decide what to fix. The default launch gate blocks on high and critical findings:

  • Exit 0: the selected threshold passed and coverage is complete.
  • Exit 1: the command failed.
  • Exit 2: findings met --fail-on, or coverage was incomplete or malformed.

If you believe a result is a false positive, report its detector, source, and why it is benign. Do not include unredacted credential values in an issue.

Chrome extension

The extension observes request and response metadata, page content, and fetch/XHR responses locally. It redacts stored and copied findings, keeps raw finding values in service-worker memory, and lets you pause collection for an origin. nativeMessaging is used for explicit full scans through the installed local helper; it sends fixed lifecycle actions, a startup challenge, and local proof, not page URLs or scan data.

  • Install the published Chrome Web Store extension (listing version 1.2.0).
  • Download extension v1.3.0 from the GitHub release. This ZIP is available for unpacked testing; it has not been submitted to the store listing.
  • For local development, load the extension/ directory in chrome://extensions, then run poetry run keyleak install-extension-host from a source checkout. The helper restricts access to the exact extension origin.

Static browser app and GitHub Pages

The browser app scans pasted text, selected files/folders, ZIP text entries and embedded source-map contents on the visitor's device. A Web Worker runs the shared JavaScript detector; redacted history stays in IndexedDB and reports can be exported as JSON, SARIF, Markdown or HTML. Local scans work offline once the app assets have cached successfully.

Build and preview the static app with no application server or runtime packages:

python scripts/build_browser_app.py
python -m http.server 8080 --directory dist/browser

The included Browser app and Pages workflow tests pull requests and deploys the tested artifact after a merge to main. Select Settings → Pages → Source → GitHub Actions once to enable publication. Relative assets and workers support the project URL https://amal-david.github.io/keyleak-detector/ and custom-domain roots; the existing php-check/ utility remains in the published site.

Optional URL scanning reads one CORS-enabled HTTPS resource. Optional DNS discovery sends a bounded set of candidate names to Google Public DNS. These operations require explicit user action. This browser release does not provide the CLI's site crawl, native discovery tools, active BaaS checks or binary analysis. Browser verdicts are REVIEW, NO_FINDINGS and INCOMPLETE; a result only describes the selected checks.

See the browser app guide for setup, privacy boundaries, supported inputs, limits and deployment verification.

What it detects

  • API credentials, private keys, JWT risks, and secrets in browser responses or local files.
  • Supabase, Firebase, Appwrite, PocketBase, and Convex configuration or access-control issues.
  • Risky npm lifecycle hooks, CI workflow settings, exposed local configuration, and selected build artifacts.
  • Opt-in application-security and correctness leads, labeled for review when they are not validated exploits.

KeyLeak complements dedicated source-secret scanners and DAST tools. It is not a general exploit framework. See Convex support and safety boundaries for provider-specific limits.

GitHub Action

Use the GitHub Action guide to scan a deployment or repository in CI. The action supports browser and local modes, SARIF upload, and configurable failure thresholds.

Development

git clone https://github.com/Amal-David/keyleak-detector.git
cd keyleak-detector
poetry install
poetry run playwright install chromium
poetry run keyleak local . --launch-profile launch-gate --fail-on high

To run the Flask web UI, use poetry run python app.py and open http://127.0.0.1:5002. For detector contributions, see CONTRIBUTING.md and the detector authoring guide.

Releases and documentation

The current Python package release is 0.7.0. The extension Web Store listing and downloadable ZIP can have different versions because store updates require a separate submission.

The browser site deploys from tested main builds. Publishing a versioned GitHub Release triggers PyPI publication and attaches the Python distributions, extension ZIP and checksums to that release. See release channels and setup.

Security and maintenance

Amal David (@Amal-David) is the project and security maintainer. See SECURITY.md for responsibilities and private vulnerability reporting, and MAINTAINERS.md for review ownership. Distribution readiness tracks packaging checks and remaining work; it does not imply official distribution or program acceptance.

License

MIT. See LICENSE.

About

Runtime leak detector for modern web apps - finds exposed API keys, validates BaaS misconfigurations (Supabase/Firebase RLS), and catches secrets in JS bundles. Chrome extension + CLI.

Topics

Resources

Contributing

Security policy

Stars

276 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages