npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vibe-audit-security

v0.1.0

Published

Security scanner for vibe-coded projects: local CLI and MCP server that catch the security mistakes an AI coding assistant can silently introduce (hardcoded secrets, disabled RLS, open CORS, missing security headers) before you push.

Readme

vibe-audit

A local security scanner for vibe-coded projects, apps built with AI coding assistants (Claude, Cursor, etc). It catches the kind of security mistakes an AI assistant can introduce without anyone noticing: hardcoded API keys, disabled Row Level Security, wide-open CORS, missing security headers, and more, before you git push or deploy.

It ships as both a CLI and an MCP server you can wire into Claude Code, so Claude can scan your project and summarize the findings in plain language as part of your normal workflow.

⚠️ Legal disclaimer

Only scan projects, domains, or servers that you own or have explicit authorization to test. The dynamic scanner (scan-url) sends real HTTP requests to the target. Scanning a system you don't own or don't have permission to test may violate the Computer Fraud and Abuse Act (US), the Computer Misuse Act (UK), similar laws elsewhere, or a service's terms of use. You are solely responsible for how you use this tool. This disclaimer is also printed every time you run the CLI. The --probe-database flag prints an additional warning before it runs, since it sends extra requests to your database's REST API (still read-only, see below).

What it checks

Mode 1: scan-code (static, local project directory)

  • Hardcoded secrets: Stripe live keys, AWS access keys, Google API keys, GitHub tokens, Slack tokens/webhooks, PEM private key blocks, database connection strings with embedded credentials.
  • .gitignore gaps: missing .gitignore, or sensitive files present in the project (.env, *.pem, *.key, cloud credential files) that aren't actually covered by it.
  • Database rules: Supabase/Postgres migrations (supabase/migrations/*.sql) that create a table without a matching ENABLE ROW LEVEL SECURITY, and firestore.rules files with unconditional allow ...: if true rules.
  • Dangerous CORS config: Express cors() / FastAPI CORSMiddleware (or raw headers) combining a wildcard/any origin with credentials enabled.
  • Risky code patterns: eval(), the Function constructor, disabled TLS verification (verify=False, rejectUnauthorized: false,NODE_TLS_REJECT_UNAUTHORIZED=0), hardcoded debug mode, and SQL built by string concatenation/interpolation instead of parameterized queries.
  • Vulnerable dependencies: wraps npm audit and (if installed) pip-audit for whichever manifests are present.

Mode 2: scan-url (dynamic, a running URL)

  • Missing security headers: CSP, HSTS, X-Frame-Options, X-Content-Type-Options.
  • CORS: wildcard or arbitrary-origin reflection combined with Access-Control-Allow-Credentials: true.
  • Cookies missing Secure, HttpOnly, or SameSite.
  • Exposed sensitive files: .env, .git/config, .git/HEAD, config backups, etc, with a baseline check against a random nonexistent path so a single-page app that returns 200 for every route doesn't flood you with false positives.
  • Client-side secrets: the same secret patterns as mode 1, scanned against the rendered HTML and same-origin JS bundles.
  • Supabase RLS probe (opt-in, --probe-database only): detects a Supabase project URL + anon key in client-side code, then sends read-only GET requests to a fixed list of common table names (users, profiles, customers, accounts, orders, messages, leads) to check whether RLS actually blocks anonymous access. Never writes, updates, or deletes anything, and never prints row contents, only whether access succeeded.

scan-project runs mode 1 and (if a URL is given) mode 2, and merges the results into one report.

Built-in limitations (by design)

  • CORS/secret detection is regex/heuristic-based, not a full AST parse, this keeps the dependency footprint small but can occasionally miss an unusual code shape or produce a rare false positive.
  • scan-code only looks at root-level package.json / requirements.txt/pyproject.toml/Pipfile for dependency auditing (no monorepo/workspace traversal yet).
  • .gitignore matching is a simplified glob matcher, not full gitignore semantics (no nested negation rules, for example).

Suppressing a false positive

If a specific line is a genuine false positive (or intentionally demonstrates a pattern, e.g. in docs or tests), add vibe-audit-ignore anywhere in a comment on that line or the line above it, same convention as eslint-disable-line. This suppresses every finding on that line.

Installation

Run it directly with npx, no install required:

npx vibe-audit-security scan-code .

Adding it to Claude Code as an MCP server

claude mcp add vibe-audit -- npx vibe-audit-security mcp

This registers three tools (scan_code, scan_url, scan_project) that Claude Code can call directly in conversation. See Using it from Claude Code below for how to make Claude use it proactively before a push.

Installing as a Claude Code plugin

/plugin marketplace add ShadowwMaliqua/vibe-audit-security
/plugin install vibe-audit-security@vibe-audit-security-marketplace

This installs the MCP server the same way as the claude mcp add command above, packaged as a plugin.

Usage

# Scan the current directory's source code
vibe-audit scan-code .

# Scan a running app (only targets you own/are authorized to test)
vibe-audit scan-url http://localhost:3000

# Scan both and merge into one report
vibe-audit scan-project . --url http://localhost:3000

# Also probe Supabase RLS read-only (prints an extra warning first)
vibe-audit scan-url https://your-app.example.com --probe-database

Common options (available on all three scan-* commands):

| Option | Description | |---|---| | -f, --format <json\|markdown\|pdf\|all> | Which report file(s) to write (default: all) | | -o, --out <dir> | Directory to write reports into (default: .) | | -s, --severity-threshold <critical\|high\|medium\|low\|info> | Prints an advisory push/no-push recommendation based on this threshold | | --probe-database | (scan-url/scan-project only) opt-in, read-only Supabase RLS probe |

Every scan writes vibe-audit-report.json, vibe-audit-report.md, and/or vibe-audit-report.pdf depending on --format. The PDF includes a cover page with a score (0–100) and letter grade (A–F), a color-coded summary by severity, and one section per finding, sorted worst-first, with every secret masked, a plain-language description, and a concrete recommendation.

Exit codes: 0 normally, 2 if any critical finding was found (for use in a pre-commit hook or CI gate if you want one, this isn't wired up by default), 1 on an error (e.g. an SSRF-blocked target).

Using it from Claude Code

Once added as an MCP server, copy this into your own project's CLAUDE.md (the full version is in docs/example-claude-md.md):

## Security scanning before push

This project uses vibe-audit (an MCP tool) to catch security mistakes before
they get pushed or deployed.

- Before suggesting or running `git push` (or a deployment), offer to run the
  `scan_code` tool and summarize the results in plain language: how many
  issues were found, split by severity, and a short list of the critical/high
  ones with their one-line fix.
- Do not block the push. Inform the user of what was found, especially
  critical and high severity findings, and let them decide whether to fix
  first or push anyway. The default behavior is advisory, not enforced.
- Exception: if the user has explicitly asked for a "strict" mode, respect
  that instead.

The default behavior is intentionally advisory: Claude informs and recommends, it never categorically refuses to help you push. You stay the decision-maker, unless you've explicitly told it otherwise.

Security posture of vibe-audit itself

Since this tool scans other people's projects, it needs to be trustworthy:

  • SSRF guard: scan-url resolves DNS once, validates every returned address (blocking RFC1918 private ranges, loopback, link-local, and cloud metadata endpoints like 169.254.169.254), and connects only to that validated address (never a second, independent DNS lookup) to close the classic DNS-rebinding TOCTOU gap. Every redirect hop is re-validated the same way (never followed automatically). localhost/127.0.0.1 are allowed only when explicitly targeted.
  • GET/HEAD only, always: no scan ever sends a write request. The Supabase RLS probe only reads, and never returns row contents in a report.
  • Secrets are always masked before they can appear in any report or log, see core/mask_secret.ts, exercised by dedicated tests.
  • Strict timeouts and response size caps on every outgoing request.
  • CI runs Gitleaks on every push/PR, plus npm audit, build, and the full test suite.

Development

npm install
npm run typecheck
npm run build
npm test
npm run dev -- scan-code .   # run from source via tsx, no build needed

See CLAUDE.md for the architecture and conventions used in this repo.

License

MIT, see LICENSE.