xploitscan
v1.12.0
Published
AI security scanner for vibe-coded apps. Find vulnerabilities before attackers do.
Maintainers
Readme
XploitScan
Security scanner for AI-generated code. Find vulnerabilities before attackers do.
Built for developers shipping code via Cursor, Lovable, Bolt, Replit, and Claude Code. 210+ security rules. Plain-English results. Copy-paste fixes.
Quick Start
npx xploitscan scan .No install, no config, no account required. Your code stays 100% local.
What It Catches
Intent check
If your project has a README, a CLAUDE.md, an AGENTS.md, a .cursorrules
file or a .xploitscan-intent file, the scan also compares what you wrote
down against what the code does:
Intent check — 1 place the code disagrees with what you wrote down
README.md:5 "Every API route requires the user to be logged in."
so the endpoint rejects unauthenticated callers
✗ /api/orders (app/api/orders/route.ts:3) — API Route Missing AuthenticationEvery line points at a finding the scan already produced, with a file and a line. It never guesses: a claim the scan cannot dispute is left alone rather than reported as a pass.
It reads whatever your project already has: README.md, CLAUDE.md,
AGENTS.md, .cursorrules, .cursor/rules/*.mdc, .windsurfrules,
.github/copilot-instructions.md, .bolt/prompt, and saved AI chat
transcripts under .specstory/history/ — where only your turns are read, not
the assistant's.
If none of those exist, say it in one line:
xploitscan intent # asks once, saves to .xploitscan-intent
xploitscan scan . --intent "Customers only see their own orders."A scan with no spec on disk offers to ask, but only in a real terminal — never
in CI, never when piped, and never inside a git hook. --no-intent-prompt
turns it off entirely.
214 rules across 14 categories:
| Category | Examples | Rules | |----------|---------|-------| | Secrets | Hardcoded API keys, .env files, OAuth secrets, Terraform state | 15+ | | Injection | SQL, XSS, SSRF, command injection, path traversal, XXE, SSTI | 20+ | | Authentication | Missing auth, weak JWT, insecure password reset, OAuth flaws | 15+ | | Cryptography | Weak RSA, deprecated TLS, ECB mode, hardcoded IVs | 10+ | | Infrastructure | Dockerfile, Kubernetes, Terraform, AWS IAM misconfigs | 10+ | | Supply Chain | Unpinned GitHub Actions, vulnerable dependencies | 5+ | | Information Leakage | PII in logs, unencrypted DB fields, exposed admin routes | 10+ | | Code Quality | Console.log in production, empty catch blocks, TODO/FIXME | 10+ |
Every finding includes OWASP Top 10 and CWE compliance mappings.
Detection Quality
Detection is scored publicly on a labeled fixture corpus that's refreshed on every commit. Current numbers live at xploitscan.com/benchmark:
- 100% precision (zero false positives) across a 200+ fixture labeled corpus covering 25+ vulnerability classes
- 98%+ recall — live numbers at xploitscan.com/benchmark
- Side-by-side comparison with Semgrep (community rulesets) and Bearer on the same corpus
The scanner uses a two-layer architecture: a fast regex pre-filter for pattern-based rules (secrets, missing headers, container misconfigs), and a Babel-parsed AST layer with local taint tracking for data-flow rules (SSRF, prototype pollution, mass assignment, SSTI, command injection from user input). Recognized taint sources: Express / Fastify / Koa / Next.js App Router / Web Fetch API / AWS Lambda.
Methodology, fixture format, and reproducibility instructions: xploitscan.com/docs/detection-methodology.
Installation
# Run directly (recommended — always latest version)
npx xploitscan scan .
# Or install globally
npm install -g xploitscan
xploitscan scan .Usage
# Scan current directory
npx xploitscan scan .
# Scan a specific folder
npx xploitscan scan ./src
# JSON output (for scripting/CI)
npx xploitscan scan . --format json
# SARIF output (for GitHub Security tab)
npx xploitscan scan . --format sarif
# Scan only changed files vs main branch
npx xploitscan scan . --diff
# Watch mode — re-scan on file changes
npx xploitscan scan . --watchOutput Formats
| Format | Use Case |
|--------|----------|
| text | Human-readable terminal output (default) |
| json | Machine-readable JSON with all findings |
| sarif | GitHub Security tab integration |
GitHub Action
Add automated scanning to every PR:
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run XploitScan
uses: bgage72590/xploitscan@main
with:
path: '.'
format: 'sarif'
fail-on: 'critical'
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: xploitscan-results.sarifFindings appear in the GitHub Security tab as code scanning alerts.
Configuration
Create a .xploitscanrc file in your project root. Every key below is read by
the scanner; there are no others.
{
"ai": false,
"scan": {
"exclude": ["docs/**", "examples/**"],
"extensions": ["liquid", "hbs"],
"maxFileSize": 500000,
"gradeVendored": false,
"failOnQuality": false
},
"rules": {
"disable": ["VC042", "QA005"]
},
"output": {
"format": "terminal",
"verbose": false
}
}| Key | Effect |
| --- | --- |
| ai | Turn off the AI false-positive pass, the same as --no-ai. |
| scan.exclude | Extra ignore patterns, .gitignore syntax, on top of .gitignore and .xploitscanignore. |
| scan.extensions | Additional file extensions to read. Added to the built-in list, never replacing it — otherwise one unusual extension would silently turn off every default and hand you a clean report because nothing was scanned. |
| scan.maxFileSize | Skip files larger than this many bytes. |
| scan.gradeVendored | Count findings in vendored/generated/docs paths toward the grade and the exit code. Off by default; they are reported either way. |
| scan.failOnQuality | Let quality findings (QA…) set a non-zero exit code. Off by default. |
| rules.disable | Rule IDs to turn off entirely, security or quality. |
| output.format | terminal, json, sarif, splunk-hec, elastic-ecs, datadog-logs. |
| output.verbose | Extra detail during the scan. |
To ignore paths, or to silence specific rules on specific paths, use
.xploitscanignore below — it is more precise than scan.exclude and is the
mechanism the scanner itself uses.
.xploitscanignore
A .gitignore-style file in your project root. Plain lines exclude whole
files from scanning (negate with !). A line may also carry a trailing
rule-ID list to suppress only those rules on matching paths while still
scanning the files for everything else:
# Don't scan generated code at all
generated/**
# Allow log-injection (VC044) in internal cron scripts only
scripts/cron/** VC044
# Silence two rules across all test files
**/*.test.ts VC031, VC043
# Suppress every rule on a legacy tree (the `scanner` wildcard)
legacy/** scannerFor a single reviewed-and-accepted finding, prefer an inline
// VC<id>-OK: <reason> comment instead of a file- or path-wide rule. Put it on
the flagged line or anywhere in the comment block above it; // scanner-OK:
silences any rule at that site. Every rule honours them, security and quality
alike. # and /* */ work as well as //.
Where it is looked up. Every .xploitscanignore between your project root
and the directory being scanned applies, so xploitscan scan packages/web/src
still honours the file at the top of the repo. Patterns are interpreted
relative to the file that declares them — a root file naming
packages/web/src/lib/demo.ts matches that file whether you scan the repo root
or packages/web/src — and a nested file takes precedence over a broader rule
above it, the same way .gitignore does.
Vendored and generated code
Some of what a scanner finds isn't code you wrote. AI app builders copy
shadcn/ui into your project verbatim; codegen writes into __generated__/;
your README contains example code that exists to show what not to do.
XploitScan scans all of it and reports everything it finds — but findings in these paths don't count toward your grade or the CI exit code:
**/components/ui/** **/shadcn/** **/ui/shadcn/**
**/vendor/** **/vendored/** **/third_party/**
**/generated/** **/__generated__/**
**/*.md **/*.mdx
.claude/** .agent/** .cursor/** .superpowers/** .windsurf/**They still appear in every report, tagged [not graded], with the count shown
next to the grade. Nothing is hidden — a grade that held findings out always
says so.
Hardcoded credentials are the exception and are always graded, in every
path above. A key committed to your repository is live no matter which
directory holds it, so "the generator wrote that file" doesn't apply. A
service-role key in __generated__/client.ts or a plaintext Kubernetes Secret
under generated/ still counts against your grade.
Why: shadcn's chart.tsx writes CSS custom properties through
dangerouslySetInnerHTML, which trips a critical XSS rule. It ships
byte-identically in a large share of AI-scaffolded projects, and one critical
caps a project at grade D. Grading it means grading shadcn's code as yours.
To opt out and grade everything:
xploitscan scan . --grade-vendoredOr persistently, in .xploitscanrc:
{ "scan": { "gradeVendored": true } }Web Dashboard
Scan via the web at xploitscan.com:
- Drag-and-drop file/ZIP upload
- GitHub URL scanning
- Scan history and score trends
- PDF security reports
- SOC2/ISO27001 compliance mapping
- Slack and Discord webhook notifications
Free: 5 scans/day, 30 core rules. Indie ($9/mo): 500 scans/month, all 210+ rules, scan history. Pro ($19/mo): unlimited scans, all 210+ rules, PDF reports, compliance mapping, webhooks, AI false-positive filter. Team ($99/mo): everything in Pro plus 5 seats, shared scan history, RBAC, and portfolio reports. Annual plans save 40%.
Supported Languages
JavaScript, TypeScript, Python, Ruby, Go, Rust, Java, PHP, Swift, Kotlin, C#, Dart, C/C++, and configuration files (Dockerfile, Terraform, Kubernetes, GitHub Actions, .env).
Links
- Website: xploitscan.com
- Documentation: xploitscan.com/docs
- Changelog: xploitscan.com/changelog
- Email: [email protected]
License
MIT -- Cipherline LLC
