Rozhanitsy Devlog 2
Vuln intel service — feed it installed software, get back which CVEs actually apply to it. 27 commits, empty lockfile to a dockerized app with a working sync pipeline and admin panel.Started with the schema: CpeMap, Product, Vendor, Vulnerability, VulnerabilityRange, ScanHost, Source, SyncState. That’s basically the whole app in one commit — vendors/products are a catalog I curate, CVEs link to them through ranges, hosts get matched against those ranges via CPE strings. Seeded sources instead of hardcoding “nvd” everywhere, since I figured I’d want other feeds eventually.Added scan_logs and unmatched_lookups, folded the 2FA columns migration into the users table migration instead of leaving it bolted on separately. Wrote VersionComparator, gave NVD explicit precedence over whatever else might get added later.Pulled in Sanctum, cleaned out migration cruft, updated models to match.Core loop went in next: SyncNvdVulnerabilities command, VulnCheckController, rate limiting, POST /api/vulns/check. CPE lookup → range join → version comparison → vulnerable list, with unmatched stuff parked in its own table so I can go add it to the catalog later instead of it just vanishing. Wrote a pile of tests right after — factories for everything, sync tests, vuln check tests, CPE resolver tests, rate limit tests.Small cleanup pass: slugs in the seeder, more test coverage. Then went back and tore hardcoded NVD assumptions out of the sync command and controller — added a migration so sources can carry their own driver config instead of assuming NVD forever. Wanted that fixed before the app grew around the assumption.Docker next — Dockerfile, compose, entrypoint, opcache config, a CreateScanHost command for provisioning from the CLI. Then the whole frontend in one go: dashboard, a tokens page so scan hosts can self-serve Sanctum tokens, admin dashboard, admin user management, GrantAdmin command, rewrote Welcome (cut it by more than half, mostly bloat). Wired up HandleInertiaRequests so props actually reach the frontend.Wrote the wiki same day as the features it documents — API reference, CLI reference, deployment, schema, operations. Doing it same-day beats doing it a month later once I’ve forgotten why something works the way it does.Found and fixed a memory leak in the sync command — only showed up once I ran it against the real NVD feed instead of test fixtures. Built out actual vendor/product matching: RelinkVulnerabilityRanges command, an admin products page for curating the catalog through the UI, vendor/product seeders with a real starter set.Then a commit I titled, honestly, “deshittified plugin detection.” Pulled the matching logic out of the sync command into its own VulnerabilityRangeBuilder, added an OR-group clause to vulnerability_ranges so one CVE can express “affects 1.2–1.5 OR 2.0–2.3” without hacks, added RebuildVulnerabilityRanges to regenerate ranges without re-hitting NVD. Every project has one of these commits where you fix the thing you hated three days ago.Simplified SECURITY.md, moved the wiki over to GitHub’s wiki and trimmed the in-repo copies to a README with links, merged, added CI and dependabot. Then put the full wiki files back in the repo right after — GitHub wikis are a separate repo under the hood and they drift, didn’t want to rely on it alone.Last commit: made the vuln-check API return a confidence level when it can’t pin down a version instead of silently guessing. Better to say “not sure, but here’s our best guess” than fake precision.Net result: NVD ingest → CPE resolution → version ranges → match API, admin UI to curate the catalog, dockerized, test coverage across the sync command, comparator, API, rate limits, and admin auth.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.