Skip to content

Repository files navigation

Security Vulnerability Dashboard

Deploy static content to Pages

A comprehensive React + TypeScript dashboard for visualizing and analyzing security vulnerabilities in software ecosystems. This application provides powerful filtering, visualization, and analysis capabilities for large-scale vulnerability datasets.

Live deployment: Vercel | GitHub Pages

Table of Contents

Features

Core Functionality

  • Large Dataset Handling: Efficiently processes and displays vulnerability data files (300MB+)
  • Advanced Filtering: Filter vulnerabilities by severity, status, package name, and more
  • Analysis Modes:
    • Analysis Mode: Filters out CVEs with kaiStatus "invalid - norisk"
    • AI Analysis Mode: Filters out CVEs with kaiStatus "ai-invalid-norisk"
  • Intelligent Search: Debounced search with live suggestions, hints, and contextual matches
  • Interactive Visualizations: Severity distribution, risk factor frequency, trend analysis, and an AI vs manual relationship bar chart that surfaces absolute triage counts for each decision bucket
  • Vulnerability Comparison: Select up to 4 vulnerabilities from the dashboard list and compare them side-by-side with a persistent selection bar
  • Theme Controls: One-click dark/light mode toggle plus palette options for charts
  • Data Export: Export filtered data as JSON or CSV

Technical Highlights

  • Virtualization: Efficient rendering of large vulnerability lists (density adapts to user preference)
  • State Management: React Context API + React Query for optimal data handling
  • Persisted Preferences: User-configurable defaults, chart palettes, animation controls, and compare selections saved to localStorage
  • Type Safety: Full TypeScript implementation with comprehensive type definitions
  • Performance Optimized: Code splitting, memoization, and lazy loading across routes and heavy components
  • Modern UI: Built with Chakra UI and Framer Motion for smooth animations
  • Resilient Data Loading: Fetches the upstream ui_demo.json dataset with automatic fallbacks to the bundled copy and synthetic mock data
  • Status Normalization: Harmonizes upstream status strings (e.g., numerous "fixed in …" values) to the Kai Cyber classifications for accurate pie and bar charts while keeping raw values available for drill-downs

Tech Stack

  • React 18 with TypeScript
  • Vite - Fast build tool and dev server
  • React Router - Client-side routing
  • React Query (@tanstack/react-query) - Server state management and caching
  • Chakra UI - Component library
  • Recharts - Data visualization
  • Framer Motion - Animations
  • React Window - Virtualization for large lists

Project Structure

vulnerability-visualizer/
├── public/
│   └── ui_demo.json          # Vulnerability data file (Git LFS)
├── src/
│   ├── components/           # Reusable UI components
│   │   ├── AnalysisButtons.tsx        # Analysis mode filter buttons
│   │   ├── Charts.tsx                 # Data visualization suite
│   │   ├── CompareSelectionBar.tsx    # Floating compare selection bar with summary metrics
│   │   ├── CriticalHighlights.tsx     # Spotlight on high-impact vulnerabilities
│   │   ├── FilterBar.tsx              # Search, suggestions, and filter interface
│   │   ├── Layout.tsx                 # Main layout wrapper + preferences entry point
│   │   ├── PreferencesDrawer.tsx      # User customization controls
│   │   ├── StatsCards.tsx            # Statistics summary cards
│   │   └── VulnerabilityList.tsx      # Virtualized vulnerability table with compare toggles
│   ├── context/
│   │   ├── __tests__/                 # Context tests
│   │   │   └── CompareSelection.test.tsx  # Compare workflow tests
│   │   ├── UserPreferencesContext.tsx # Persisted user settings
│   │   └── VulnerabilityContext.tsx   # Global vulnerability state management + compare selection
│   ├── hooks/
│   │   ├── useDebounce.ts         # Debounce hook for search
│   │   ├── useLocalStorage.ts     # LocalStorage-backed state helper
│   │   └── useVulnerabilityData.ts # React Query hook for data loading
│   ├── pages/
│   │   ├── Dashboard.tsx          # Main dashboard page
│   │   ├── VulnerabilityDetail.tsx # Individual vulnerability view
│   │   └── Comparison.tsx         # Vulnerability comparison page
│   ├── types/
│   │   └── vulnerability.ts       # TypeScript type definitions
│   ├── utils/
│   │   ├── dataLoader.ts          # Data loading utilities
│   │   ├── dataProcessor.ts       # Filtering and processing logic
│   │   └── export.ts              # Export functionality
│   ├── App.tsx                    # Main app component
│   ├── main.tsx                   # Application entry point
│   └── theme.ts                   # Chakra UI theme configuration
├── package.json
├── tsconfig.json
└── vite.config.ts

Installation

Prerequisites

  • Node.js 18+ and npm/yarn/pnpm
  • Git LFS (if working with the actual ui_demo.json file)

Setup Steps

  1. Clone the repository

    git clone <repository-url>
    cd vulnerability-visualizer
  2. Install Git LFS (if needed for ui_demo.json)

    git lfs install
    git lfs pull
  3. Install dependencies

    npm install
    # or
    yarn install
    # or
    pnpm install
  4. (Optional) Pull the full dataset locally before starting dev:

    npm run prebuild

    Skip this step if you are happy using the bundled sample data.

  5. Start the development server

    npm run dev
    # or
    yarn dev
    # or
    pnpm dev
  6. Open your browser Navigate to http://localhost:3000

Data Format

The application expects vulnerability data in JSON format. The data loader supports multiple formats:

Supported Formats

  • Array of vulnerabilities: [{...}, {...}]
  • Object with vulnerabilities key: { vulnerabilities: [...] }
  • Object with data key: { data: [...] }
  • Hierarchical object with groups -> repos -> images -> vulnerabilities (as provided by the upstream dataset)

Vulnerability Object Structure

{
  id: string;                    // Unique identifier
  cveId?: string;                // CVE identifier
  packageName?: string;          // Affected package name
  packageVersion?: string;       // Package version
  severity?: 'critical' | 'high' | 'medium' | 'low' | 'info' | 'unknown';
  kaiStatus?: 'invalid - norisk' | 'ai-invalid-norisk' | 'valid' | 'ai-valid' | 'pending' | 'unknown';
  score?: number;                // Vulnerability score
  cvss?: {                      // CVSS details
    version?: string;
    baseScore?: number;
    vector?: string;
  };
  description?: string;          // Vulnerability description
  publishedDate?: string;        // ISO date string
  modifiedDate?: string;         // ISO date string
  riskFactors?: Array<{         // Risk factor data
    name: string;
    value: string | number;
    category?: string;
  }>;
  references?: string[];        // Reference URLs
}

Usage

Dashboard View

The main dashboard displays:

  • Statistics Cards: Overview of vulnerabilities by severity
  • Filter Bar: Intelligent search, live suggestions, and filters
  • Analysis Mode Buttons: Quick filters for analysis workflows
  • Charts: Severity, risk factors, trend analysis, and AI vs manual relationship
  • Critical Spotlight: Highlights the most urgent items after filtering
  • Vulnerability List: Virtualized, density-aware table of all vulnerabilities

Filtering Vulnerabilities

  1. Search: Type in the search box to filter by CVE ID, package name, or description. The suggestion drawer offers context-aware recommendations, quick severity/status filters, and description matches.
  2. Severity Filter: Select a severity level from the dropdown
  3. Status Filter: Filter by kaiStatus value
  4. Analysis Modes:
    • All Vulnerabilities: Shows all data
    • Analysis: Excludes "invalid - norisk" CVEs
    • AI Analysis: Excludes "ai-invalid-norisk" CVEs

Viewing Details

Click on any CVE ID in the vulnerability list to view detailed information including:

  • Basic information (CVE ID, package, severity, status)
  • Description
  • CVSS scores
  • Risk factors
  • Dates
  • References
  • Add to Compare: Use the "Add to Compare" button on the detail page to add the vulnerability to your comparison set

Comparing Vulnerabilities

  1. Select vulnerabilities: Click the "Compare" button on any vulnerability row in the dashboard list (or use the "Add to Compare" button on detail pages)
  2. Review selection: A floating selection bar appears at the bottom showing your selected items (up to 4), summary metrics, and quick actions
  3. Compare: Click "Compare" in the selection bar to navigate to the comparison page, or visit the "Compare" tab directly
  4. Persistent selection: Your compare selections are saved to localStorage and persist across page reloads

Exporting Data

Use the "Export JSON" or "Export CSV" buttons on the dashboard to export the currently filtered dataset.

Personalizing the Dashboard

  • Open the settings icon in the header to choose default analysis mode, table density, animation preference, and chart palette.
  • Preferences are stored locally, so your preferred layout persists between sessions.

Performance Optimizations

  1. Virtualization: Large lists use react-window with overscan tuning and density preferences
  2. Debounced Search: Search input is debounced to reduce filtering operations
  3. Memoization: Components and computations are memoized where appropriate
  4. Code Splitting: Routes are lazy-loaded for faster initial load
  5. React Query: Intelligent caching and data fetching
  6. Palette-aware Rendering: Visualization components adapt to colorblind-friendly or night modes
  7. Resilient fetching: Remote dataset is retrieved from GitHub with graceful fallback to the local copy or generated mock data
  8. Full-dataset visualization: The dashboard renders all 236k+ upstream exposure records, while export utilities still deduplicate by CVE when generating CSV/JSON handoffs

Data Source

  • Primary dataset: ui_demo.json
  • The runtime loader first prefers the remote URL, then the build-time copy at /ui_demo.json, and finally the curated sample (/ui_demo.sample.json) before generating mock data.
  • When targeting GitHub Pages set DEPLOY_TARGET=github-pages (the workflow already does this) so Vite outputs to dist-github-pages and uses the repository sub-path. For Vercel/Netlify or local builds leave DEPLOY_TARGET unset to build into dist with a site root base.
  • When the prebuild fetch succeeds the build script sets VITE_DATA_SOURCE=prebuilt so the UI surfaces the badge as remote (prebuilt) (indicating the upstream dataset was bundled during the build). Leave this unset when you want to rely on runtime fetching.
  • As a last resort, realistic mock data is generated so the dashboard always renders. The source badge communicates:
    • remote – fetched live from GitHub at runtime
    • remote (prebuilt) – upstream dataset downloaded during the build and served from the static host/CDN
    • local sample – bundled curated sample for offline demos
    • mock – generated fallback when neither upstream nor bundled data is reachable

Development

Available Scripts

  • npm run prebuild pulls the canonical dataset into public/ui_demo.json using scripts/fetch-data.mjs. This step runs automatically during npm run build (for Vercel or local production builds). The script understands Git LFS pointers and will dereference them to download the real payload from media.githubusercontent.com.
  • npm run dev - Start development server
  • npm run build - Build for production
  • npm run preview - Preview production build
  • npm run lint - Run ESLint
  • npm run type-check - Validate TypeScript types with tsc --noEmit
  • npm run test - Execute the Vitest + Testing Library suite

Deployment

  • GitHub Pages: Automated via .github/workflows/deploy.yml. Builds with DEPLOY_TARGET=github-pages, skips the runtime fetch (SKIP_DATA_FETCH=true), and publishes the prebuilt artifact from dist-github-pages/.
  • Vercel: Imports directly from GitHub. Leave DEPLOY_TARGET unset so build output lands in dist/. npm run build still runs prebuild, ensuring the canonical dataset is bundled even when GitHub Pages is not the target.

Planning Docs

The active and future backlog files are the canonical work queues. Release notes, architecture docs, and QA reports can provide context, but new work should be promoted into one of the backlog files.

Beyond the Requirements

  • Persisted user preferences (analysis defaults, density, chart palette, animation toggle)
  • Intelligent search suggestions with quick severity/status pivots
  • Virtualized list with adaptive density and optional animations
  • Filter impact meter quantifying how many CVEs are hidden by the current filters
  • Manual vs AI analysis comparison using a grouped bar chart with absolute counts
  • Improved compare workflow: Select vulnerabilities directly from the dashboard list with a persistent selection bar showing summary metrics (highest severity, average score, status breakdown)
  • Compare selections persist across sessions via localStorage
  • Toast notifications for compare actions (add/remove/limit reached)

Release Notes

  • v1.3.0 – Full-dataset visuals, Kai status normalization, and manual vs AI bar chart
  • v1.2.0 – Dark mode toggle, lint/type/test gates, and data ingestion overhaul

Git LFS Note

  • The upstream ui_demo.json is a 300MB+ Git LFS object. Run git lfs install && git lfs pull or execute npm run prebuild to download the full payload locally. The repository ships with a curated ui_demo.sample.json for quick demos when bandwidth or storage is constrained.

Contributing

Contributions are welcome! Fork the repository, create a branch, and open a pull request. Please run npm run lint, npm run type-check, and npm run test before submitting.

License

MIT License. See LICENSE for details.

Future Enhancements

Future work now lives in Future Backlog so the README does not become a second planning queue.

About

Interactive React + TypeScript dashboard for visualizing and filtering software vulnerabilities.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages