Sample scan output for a typical site:
┌─────────────────────────────────────────────────────────┐
│ 🔐 WebVulnScan — https://example.com │
│ Score: 74 / 100 ● 38 checks ● 312ms │
├──────────┬──────────┬──────────┬──────────┐ │
│ Critical │ High │ Medium │ Low │ │
│ 0 │ 5 │ 7 │ 4 │ │
└──────────┴──────────┴──────────┴──────────┘ │
│ │
│ ✗ HIGH Missing Content-Security-Policy │
│ ✗ HIGH Missing HSTS Header │
│ ✗ HIGH Missing X-Frame-Options │
│ ✗ MEDIUM Missing X-Content-Type-Options │
│ ✗ MEDIUM robots.txt Missing │
│ ✗ MEDIUM No Rate Limiting Detected │
│ ✓ LOW SSL Certificate Valid (365 days) │
│ ✓ LOW TLS 1.3 Active │
│ ✓ LOW Compression Enabled (br) │
│ ✓ LOW CORS: Restrictive (Good) │
└─────────────────────────────────────────────────────────┘
| Category | Checks | What It Catches |
|---|---|---|
| 🔒 SSL / TLS | 6 | Certificate expiry, weak ciphers, TLS version |
| 🛡️ Security Headers | 11 | CSP, HSTS, X-Frame, CORS, Referrer-Policy |
| 💉 Injection | 15 | XSS, SQLi, NoSQL, SSTI, XXE, LDAP, Command |
| 🍪 Cookies | 7 | Secure, HttpOnly, SameSite, expiry |
| 📁 Exposed Files | 25 | .env, .git, backups, SSH keys, phpinfo |
| 🔑 Authentication | 10 | Admin panels, JWT issues, default creds |
| 🌐 DNS & Email | 10 | SPF, DKIM, DMARC, CAA records |
| 🚀 Performance | 10 | Response time, compression, caching, CDN |
| 🔍 SEO | 13 | Title, meta, canonical, OG tags, sitemap |
| 🔐 Privacy / GDPR | 8 | Cookie consent, trackers, privacy policy |
| ♿ Accessibility | 10 | WCAG 2.1, ARIA, tab order, skip links |
| 🔗 Supply Chain | 5 | SRI hashes, outdated libraries, GTM |
| 📊 API Security | 5 | GraphQL, unauth endpoints, Swagger |
| 🏗️ Infrastructure | 5 | HTTP redirect, dev subdomains, DNSSEC |
| ⏱️ Rate Limiting | 4 | Burst detection, payload size |
# Clone
git clone https://github.com/codebytaki/webvulnscan.git
cd webvulnscan
# Install
npm install
# Run
npm startOpen http://localhost:3000 — paste any URL and hit scan. That's it.
Node.js 18+ required. No API keys. No accounts. Fully offline-capable.
Scan programmatically via the REST endpoint:
curl -X POST http://localhost:3000/api/scan \
-H "Content-Type: application/json" \
-d '{"url": "https://yoursite.com"}'Response shape:
{
"score": 74,
"totalChecks": 38,
"passedChecks": 22,
"failedChecks": 16,
"severityCounts": { "critical": 0, "high": 5, "medium": 7, "low": 4 },
"issues": [
{
"passed": false,
"severity": "high",
"cat": "Headers",
"title": "Missing Content-Security-Policy",
"description": "No CSP header...",
"fix": "res.setHeader('Content-Security-Policy', ...)"
}
],
"responseTime": 312,
"pageSize": 14820
}The scanner is fully functional without an account. To enable login + scan history:
- Create a free project at supabase.com
- Run
supabase-schema.sqlin your Supabase SQL editor - Edit
public/supabase-client.js:
constSUPABASE_URL='https://your-project.supabase.co';constSUPABASE_ANON='your-anon-public-key';// public key only — never service roleRow Level Security is enforced — users only ever see their own scans.
webvulnscan/
├── server.js ← All 150+ scan checks (Node.js / Express)
├── supabase-schema.sql ← DB schema + RLS (optional)
├── photos/ ← Screenshots for this README
├── public/
│ ├── index.html ← Landing page + inline scanner modal
│ ├── scan.html ← Full-page results view
│ ├── dashboard.html ← Scan history (requires Supabase)
│ ├── login.html ← Auth page
│ ├── app.js ← Frontend logic + result rendering
│ ├── dashboard.js ← Dashboard data loader
│ ├── supabase-client.js ← Configure your Supabase keys here
│ └── shared.css ← Global dark theme styles
└── package.json
Each check returns passed: true/false with a severity weight:
| Severity | Weight | Example |
|---|---|---|
| 🔴 Critical | 15 | SQL injection confirmed |
| 🟠 High | 8 | Missing CSP header |
| 🟡 Medium | 3 | Missing canonical tag |
| 🔵 Low | 1 | Missing Twitter card |
score = 100 − (total_penalty / max_possible_penalty × 100)
A perfect site scores 100. Real-world sites typically score 40–75.
// 1. Write your check functionasyncfunctioncheckMyThing(urlStr,body,headers){constr=[];// ... your logicr.push({passed: false,severity: 'high',// critical | high | medium | lowcat: 'Security',title: 'Short check name',description: 'What it means and why it matters.',fix: '// Optional code snippet'});returnr;}// 2. Add to the Promise.all in /api/scan// 3. Spread into allChecksPRs are welcome.
# Any Node.js host (Railway, Render, Fly.io, VPS)
PORT=8080 npm start
# Docker one-liner
docker run -p 3000:3000 -v $(pwd):/app -w /app node:18-alpine npm startBuilt by MD Taki — Security Researcher · AI Developer · Bug Hunter
MIT — free to use, modify, fork, and deploy.
Built by MD Taki — Security Researcher · AI Developer · Bug Hunter