VulnFeed 2.0: Building a Zero-Server Vulnerability Dashboard (Level 2 Release)

Published: (December 6, 2025 at 03:02 PM EST)
4 min read
Source: Dev.to

Source: Dev.to

The Problem

Most vulnerability dashboards are either:

  • Too expensive – enterprise SaaS tools with high price tags
  • Too limited – focused on one ecosystem or distribution
  • Privacy nightmares – track your data, your queries, your team
  • Too complex – require backend infrastructure to maintain

We wanted something radically different.

Enter Onyx Intelligence

Onyx is a completely static, zero‑server vulnerability dashboard that aggregates data from 25+ sources (CISA, Red Hat, all major Linux distros, npm, PyPI, Maven, RubyGems, Cargo, Composer, etc.) into one beautiful, interactive interface.

Think of it as the Level 2 evolution of VulnFeed — everything you loved, but supercharged.

Key Stats

  • 📊 25+ vulnerability data sources
  • 🔄 Auto‑updates every 6 hours via GitHub Actions
  • 🏗️ Zero backend required (GitHub Pages deployment)
  • 🔒 Zero tracking, zero data collection
  • 🎨 Beautiful glassmorphism UI with light/dark themes
  • 📱 Fully responsive (mobile, tablet, desktop)
  • 🧠 Asset exposure scanning (optional)

How It Works (The Tech)

The Data Collection Pipeline

Everything starts with a scheduled GitHub Actions workflow that runs every 6 hours:

# .github/workflows/osv-feed-update.yml
schedule:
  - cron: '0 */6 * * *'  # Every 6 hours

Here’s what happens behind the scenes:

# scripts/fetch_osv_data.py
import requests
import json
from datetime import datetime

# Fetch from OSV.dev for all ecosystems
ecosystems = ['npm', 'PyPI', 'Maven', 'Cargo', 'Go', 'NuGet', 'Composer', 'RubyGems']

for ecosystem in ecosystems:
    response = requests.get(
        'https://api.osv.dev/v1/query',
        json={'package': {'ecosystem': ecosystem}}
    )
    # Validate and deduplicate
    vulnerabilities = response.json()

    # Store as clean JSON
    with open(f'data/{ecosystem.lower()}.json', 'w') as f:
        json.dump(vulnerabilities, f)

# Also fetch CISA KEV, Red Hat, Linux distros
# Everything gets merged, validated, and deployed

The output is clean, structured JSON files ready for the frontend to consume.

Frontend Rendering

On the client side, it’s pure vanilla JavaScript with no frameworks or bloat:

// Load vulnerability data from static JSON files
async function loadVulnerabilities() {
    const response = await fetch('/data/vulnerabilities.json');
    return response.json();
}

// Build interactive visualizations with Chart.js
function renderSeverityChart(vulnerabilities) {
    const severityData = {
        labels: ['Critical', 'High', 'Medium', 'Low'],
        datasets: [{
            data: [
                vulnerabilities.filter(v => v.severity === 'CRITICAL').length,
                vulnerabilities.filter(v => v.severity === 'HIGH').length,
                vulnerabilities.filter(v => v.severity === 'MEDIUM').length,
                vulnerabilities.filter(v => v.severity === 'LOW').length
            ]
        }]
    };

    new Chart(ctx, { type: 'doughnut', data: severityData });
}

// Real‑time filtering and search (no backend calls!)
function searchVulnerabilities(query, severity, days) {
    return vulnerabilities.filter(v => 
        (v.description.toLowerCase().includes(query.toLowerCase()) ||
         v.id.includes(query)) &&
        (severity === 'ALL' || v.severity === severity) &&
        (isWithinDays(v.published, days))
    );
}

No API calls. No server requests. Just static assets and client‑side logic doing the heavy lifting.

Deployment Magic

The deployment is almost magical in its simplicity:

  1. Commit changes to your fork.
  2. GitHub Actions workflow triggers automatically.
  3. Python scripts fetch fresh data.
  4. Static HTML/CSS/JS gets generated.
  5. Deployed to GitHub Pages automatically.

Your dashboard is live at: yourusername.github.io/Onyx-Intelligence/

Key Features We Built

✅ Multi‑Source Aggregation

Instead of maintaining 25 browser tabs for different vulnerability sources, everything lives in one place:

// Single search across CISA, Red Hat, npm, PyPI, Maven, etc.
const allVulnerabilities = [
    ...cisaKEV,
    ...redHatAdvisories,
    ...npmVulnerabilities,
    ...pypiVulnerabilities,
    ...mavenVulnerabilities,
    // ... 20+ more sources
];

// Now search once and get results from everywhere
const results = allVulnerabilities.filter(v =>
    v.id.includes('CVE-2024-') ||
    v.packages.includes('lodash') ||
    v.source === 'CISA'
);
✅ Smart Filtering

Advanced filters without the backend complexity:

// Critical vulnerabilities from the last 30 days
const criticalRecent = vulnerabilities.filter(v =>
    v.cvss >= 7.0 &&
    daysOld(v.published)  v.ecosystem === 'npm');

// Combine filters
const targetedResults = vulnerabilities.filter(v =>
    (v.severity === 'CRITICAL' || v.severity === 'HIGH') &&
    v.ecosystem.includes('Linux') &&
    daysOld(v.published) <= 7
);
✅ Asset Exposure Scanner

Optional feature that scans IPs and domains against multiple intelligence sources:

// Scan an IP against Censys, Shodan, AbuseIPDB, VirusTotal
async function scanAsset(ipOrDomain) {
    const results = await Promise.all([
        fetch(`/api/scan?ip=${ipOrDomain}&provider=censys`),
        fetch(`/api/scan?ip=${ipOrDomain}&provider=shodan`),
        fetch(`/api/scan?ip=${ipOrDomain}&provider=abuseipdb`),
        fetch(`/api/scan?ip=${ipOrDomain}&provider=virustotal`)
    ]);

    return {
        censys: await results[0].json(),
        shodan: await results[1].json(),
        abuseipdb: await results[2].json(),
        virustotal: await results[3].json()
    };
}

API keys are stored safely in GitHub Secrets – never exposed in frontend code.

✅ Privacy by Design

Zero tracking. Zero data collection. Just pure, honest software:

// Only localStorage for theme preference
localStorage.setItem('theme', 'dark');
localStorage.setItem('lastViewed', 'npm');

// Everything else is session‑only, in‑memory
const sessionData = {
    currentFilters: { severity: 'HIGH', days: 30 },
    selectedVulnerability: null
};

// No Google Analytics, Mixpanel, Segment, etc.
✅ Beautiful UI

We didn’t just build a tool — we built something that looks premium:

/* Glassmorphism cards */
.vulnerability-card {
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 12px;
    padding: 1.5rem;
    transition: all 0.3s ease;
}
.vulnerability-card:hover {
    background: rgba(255, 255, 255, 0.15);
    transform: translateY(-2px);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}

/* Dark mode support */
@media (prefers-color-scheme: dark) {
    .vulnerability-card {
        background: rgba(30, 27, 75, 0.2);
        border-color: rgba(255, 255, 255, 0.1);
    }
}

/* Responsive grid */
@media (max-width: 768px) {
    .grid {
        grid-template-columns: 1fr;
    }
}

Smooth animations, light and dark themes, fully responsive.

Getting Started (Seriously, 5 Minutes)

Step 1: Fork the repository

(Further steps continue in the original article.)

Back to Blog

Related posts

Read more »