Skip to content

yipjunkai/secrets-spotter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Secrets Spotter

A Chrome extension that scans web pages and network traffic for exposed secrets in real time. Uses a Rust core compiled to WebAssembly for high-performance pattern matching against 50 secret types.

Features

  • Real-time scanning of DOM content, fetch, XHR, WebSocket, Server-Sent Events, and cookies
  • Detection patterns — AWS keys, GitHub tokens, Stripe keys, JWTs, private keys, database connection strings, and more
  • False-positive filtering using Shannon entropy, placeholder detection, code identifier rejection, and context analysis
  • JWT decoder in popup — expandable header/payload JSON view for detected JWTs
  • SPA-aware — re-scans on pushState, replaceState, popstate, and hashchange navigations
  • Fully local — no data leaves your browser

How It Works

Page loaded → interceptor.js patches fetch, XHR, WebSocket, SSE, and cookies
            → content.js extracts DOM text + structured attributes
            → Text truncated to 2 MB and deduplicated by SHA-256 hash
            → Background service worker runs WASM scanner
            → Rust matches against known-prefix and keyword patterns (RegexSet + memchr pre-filter)
            → False positives filtered (entropy, placeholders, code identifiers, English words)
            → Findings deduplicated in single O(n) pass, merged across scan batches
            → Findings shown in popup (JWTs include a decoder view)
            → SPA navigations trigger re-scan automatically

Project Structure

secrets-spotter/
├── rust-core/               # Rust WASM core
│   ├── Cargo.toml
│   └── src/
│       ├── lib.rs           # WASM entry point (scan_text, pattern_count)
│       ├── detector.rs      # Detection engine + false-positive filtering
│       ├── patterns.rs      # secret regex patterns
│       ├── types.rs         # SecretKind enum, Severity, SecretFinding
│       ├── filter.rs        # URL/content filtering (skip CDNs, media, etc.)
│       ├── cookies.rs       # Cookie parsing utility
│       └── attributes.rs    # HTML attribute extraction utility
├── extension/               # Chrome extension (Manifest V3)
│   ├── manifest.json
│   ├── background/
│   │   └── service-worker.js
│   ├── content/
│   │   ├── interceptor.js   # Network traffic capture (MAIN world)
│   │   └── content.js       # DOM scanning (ISOLATED world)
│   ├── popup/
│   │   ├── popup.html
│   │   ├── popup.js
│   │   └── popup.css
│   ├── icons/
│   └── wasm/                # Compiled WASM output (built artifacts)

Detection Strategy

Secrets Spotter uses a three-tier detection strategy (50 patterns total):

Known-prefix patterns (41)

Match by a fixed prefix or structure baked into the key itself — highest confidence.

Service Prefix/Structure
AWS Access Key ID AKIA...
AWS Temp Key (STS) ASIA...
GitHub PAT ghp_ / github_pat_
GitHub OAuth gho_
GitHub App ghu_ / ghs_ / ghr_
Private Key (PEM) -----BEGIN...PRIVATE KEY-----
Password in URL protocol://user:pass@host (incl. redis, mongodb, amqp, smtp)
JWT eyJ...eyJ...
Slack xox[bpors]-
Slack App-Level xapp-
Google API Key AIza
Stripe Secret sk_(live|test)_
Stripe Publishable pk_(live|test)_
Stripe Restricted rk_(live|test)_
Stripe Webhook whsec_
Twilio SK + 32 hex chars
SendGrid SG.
Discord Bot [MN]...(dot-separated base64)
Mailgun key-
npm npm_
PyPI pypi-
Shopify shp(at|ss|ca|pa)_
Square sq0atp-
Anthropic sk-ant-api03-
OpenAI (legacy) sk-...T3BlbkFJ...
OpenAI (new) sk-proj- / sk-svcacct-
DigitalOcean dop_v1_
Linear lin_api_
PostHog ph[cx]_
GitLab PAT glpat-
Cloudflare API cf_
Supabase Service sbp_
GCP OAuth ya29.
Hashicorp Vault hvs.
Doppler dp.(st|sa|ct).
Vercel vercel_
Databricks dapi
Grafana glsa_
Pulumi pul-
Hugging Face hf_

Keyword patterns: service-specific (4)

Match by a service name in the variable name (e.g. heroku_api_key=...).

AWS Secret Key, Heroku, Azure Subscription Key, Datadog.

Keyword patterns: generic dev words (3)

Match by common developer variable names (e.g. api_key=..., authorization: Bearer ...).

Generic API Key, Bearer Token, Generic API Token.

Entropy-based fallback (2)

Broad keyword match (key, token, secret, password, etc.) with Shannon entropy validation (min 3.5 bits/char) to catch secrets that don't match any known prefix or service keyword.

False-positive filtering

  • Placeholder detection — skips YOUR_KEY, example, test, TODO, etc.
  • Shannon entropy — rejects low-entropy values for entropy-gated patterns (UTF-8-aware, counts chars not bytes)
  • Character class diversity — requires mix of uppercase, lowercase, digits, or symbols/non-ASCII
  • English word filtering — ignores lowercase hyphenated words like my-setting
  • URL / path exclusion — ignores values that look like URLs or file paths
  • Code identifier rejection — skips camelCase, PascalCase, snake_case, SCREAMING_SNAKE, kebab-case, and dot-notation values

Configuration

SCAN_EXTERNAL_RESOURCES (interceptor.js)

Controls whether the extension re-fetches external <script src> and <link stylesheet> files to scan their contents. Default: false.

This is disabled by default because the interceptor runs in the page's MAIN world, where fetches are subject to the page's Content Security Policy (CSP). Sites with strict connect-src directives will block these fetches and log console errors. Most secrets in external scripts are already caught indirectly when the script uses them in fetch/XHR calls, which the interceptor captures.

To enable, set SCAN_EXTERNAL_RESOURCES = true in extension/content/interceptor.js.

Development

Build

Requires Rust and wasm-pack.

./scripts/build.sh

This compiles the Rust core to WASM and outputs it to extension/wasm/.

Install

  1. Run the build script
  2. Open chrome://extensions/
  3. Enable Developer mode
  4. Click Load unpacked → select the extension/ folder

Usage

Browse any website. The extension icon badge shows the count of secrets found. Click the icon to view findings grouped by severity, with redacted previews and copy-to-clipboard for full values. JWT findings include an expandable decoder with header and payload JSON.

License

Secrets Spotter is licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Secrets Spotter by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any additional terms or conditions.

About

A Chrome extension that detects exposed secrets (API keys, tokens, passwords) on web pages and in network traffic in real-time, using Rust/WASM

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Contributors