Smart Home Risk Vulnerability
AI-powered IoT vulnerability triage · Next.js · NestJS · NVD · OpenAI
Impact: Turns a CVE database that requires security expertise into a 3-click risk report any homeowner can read.
TypeScript · Next.js 14 · React · MUI · NestJS 10 · TypeORM · PostgreSQL · OpenAI GPT-4 · NVD CVE API · Docker
Problem
The NIST National Vulnerability Database is the canonical source for CVEs, but it is written for security professionals — dense JSON, CVSS vectors, no plain-language guidance. A homeowner with a smart thermostat or IP camera has no realistic way to find out whether their device is exposed, how bad it is, or what to do about it. The brief was to compress the gap between "raw CVE feed" and "actionable advice for a non-technical user."
Approach
- 01
Modelled the domain around devices, not CVEs. Category → Device → Vulnerability lets users navigate by what they own, not by a CVE ID they will never know (vulnerability.entity.ts).
- 02
Built a CVSS normalisation layer in vulnerabilities.service.ts (mapCvssMetrics) that flattens both v2 and v3.x metric shapes into one schema with safe defaults — the UI never has to branch on CVSS version.
- 03
Wrapped GPT-4 with five purpose-built prompts (threat, impact, recommendation, affected system, vulnerability name). Each prompt explicitly instructs the model not to start with hedge phrases like "In simple terms..." or "I recommend...", which cleans up rendered text without a post-processing pass.
- 04
Cached generated assessments in Postgres keyed by cveId, so the OpenAI calls (and NVD round-trip) only happen once per CVE — the second user to look up the same device gets an instant response.
- 05
Mapped severity to a 5-colour scale (green → dark red) on both a legend and per-cell in the results table, so a non-technical user can read the whole row in a glance.
Outcome
- 01
A typical device lookup returns 10–30 CVEs, each with four AI-generated paragraphs and a colour-coded risk score — render time after first lookup is dominated by the DB read, not the AI.
- 02
The same NVD response that is effectively unreadable raw becomes a paginated, sortable table a non-engineer can act on.
- 03
Architecture cleanly separates concerns: NVD ingestion, AI enrichment, and presentation can each be swapped independently (e.g. GPT-4 → a smaller model, NVD → a commercial CVE feed).
Lessons
- 01
Prompts are part of the schema. Telling GPT-4 what not to say up front ("do not start with ‘In simple terms...’") saved a whole post-processing pass and made the output paste-into-UI ready. Treat prompt text like a contract, not a suggestion.
- 02
Cache aggressively when the upstream is slow and paid. Every CVE costs five OpenAI calls; persisting by cveId turned this from an "expensive demo" into something that gets cheaper the more it is used.
- 03
Normalise at the boundary, not in the view. Collapsing CVSS v2 and v3 into one shape in the service layer meant the React table did not need a single if (version === ...) — a rule worth repeating for any project that integrates a versioned external schema.