SMBs face real website security risks — expired SSL certificates, misconfigured email authentication, exposed admin panels — but rarely have in-house security expertise or budget for dedicated tooling. CyberShield solves this by delivering professional-grade security scanning in under 90 seconds, with results in plain language, directly from a browser.
The platform was designed, built, and deployed across four sprints. A mid-project pivot from an agent-based monitoring model to a pure domain scanning SaaS — deliberately chosen for lower onboarding friction and better SMB fit — demonstrates product thinking alongside engineering execution.
The domain scanner executes all check categories concurrently using Python asyncio, returning a full scan in 5–15 seconds. Findings are scored and letter-graded automatically.
| Category | Key Checks | Max Severity |
|---|---|---|
| SSL / TLS | Cert expiry (7/30-day), TLS version, weak ciphers, CT log query, HSTS preload | Critical |
| HTTP Headers | HSTS, CSP (incl. unsafe-eval analysis), X-Frame-Options, SRI audit, TRACE detection, sensitive path exposure (/admin, /.env, /.git) | High |
| Email Auth | SPF (+all/~all/-all), DKIM (11 selectors), DMARC policy strength, MTA-STS, rua/ruf presence, SPF lookup count | High |
| DNS | DNSSEC, CAA records, AXFR zone transfer test, subdomain takeover (8 fingerprints), NS redundancy | Critical |
| Open Ports | 15 high-risk ports (Free/Plus) · 50 ports at Max including Docker API (2376), K8s (6443), etcd (2379), Jupyter (8888), Consul (8500) | Critical |
| Malware / Reputation | VirusTotal 90-vendor consensus, domain reputation score | Critical |
| Sensitive Info Leak | /.env variants, /.git/config, backup files, phpinfo.php, wp-config.php.bak (Max tier) | Critical |
| Severity | Score Deduction |
|---|---|
| Critical | −22 pts |
| High | −12 pts |
| Medium | −6 pts |
| Low | −2 pts |
| Grade | Score Range |
|---|---|
| A+ | 93 – 100 |
| A | 85 – 92 |
| B | 75 – 84 |
| C | 60 – 74 |
| D | 45 – 59 |
| F | 0 – 44 |
Users upload source files (Python, JS, PHP, etc.) for pattern-based static analysis. Detected categories:
os.getenv() insecure fallbacksverify=False)*)pickle.loads)../ sequences)| Widget | Description |
|---|---|
| Security Score | 0–100 hex badge with letter grade (A+–F) and week-over-week delta |
| Action Items | Top 3 unresolved vulnerabilities by severity with remediation guidance links |
| 30-Day Score Chart | Chart.js trend line; colour-coded green ≥80 / amber ≥55 / red <55 |
| Vulnerability List | Full findings with severity filter and per-finding resolve button |
| Security Event Feed | Chronological events within retention window; marks reviewed via ✓ |
| Blocked Threats | Monthly malicious IP connections with country breakdown |
| Scan Quota | Monthly scan usage vs. plan limit in nav bar |
scan_events to the dashboard instantly. 5-minute silent polling fallback when WebSocket is unavailable. A _pollingStarted guard prevents duplicate setInterval registration across multiple Supabase auth events (SIGNED_IN / TOKEN_REFRESHED / INITIAL_SESSION).Production bugs encountered and resolved across the development cycle — each one a real debugging problem, not a tutorial exercise.
SyntaxError: const quota declared twice inside renderDashboard(). A JS SyntaxError prevents the entire script from parsing — no event listeners attach, nothing runs.UnboundLocalError: datetime used before assignment — a from datetime import datetime inside a function body created a forward reference in Python's scoping rules.agent_api.py with a lightweight deprecated stub; moved all imports to module level.startPolling() and creating independent setInterval loops._pollingStarted boolean guard — polling initialises exactly once per page load regardless of auth event count.getSession() completing while the user was still typing; the catch(() => goStep(2)) handler triggered step change on API failure.Running signal to Windows Service Control Manager (SCM), causing SCM to time out and kill the service.service_windows.go with golang.org/x/sys SCM handler.json.Decoder cannot parse (BOM is not valid JSON).UTF8Encoding(false) — BOM-less UTF-8 output.| Item | Status | Description |
|---|---|---|
| Stripe Integration | Pending | Connect Stripe Checkout to auto-update customers.tier on subscription, enabling Plus/Max feature gates |
| Railway Cron | Pending | Schedule POST /internal/run-scheduled-scans daily — enables automated weekly/daily scans for paid tiers |
| CVE Correlation | Planned | Match detected server versions (Apache, Nginx, OpenSSL) against NVD CVE records |
| PDF Reports | Planned | Downloadable PDF scan reports for B2B client reporting |