Skip to content

feat(catalog): publish machine-readable CVE→exercise manifest for external consumers #139

@pparage

Description

@pparage

Problem

range42-catalog already hosts ~14 CVE-labelled exercises under 03_container_layer/docker/_ctf/cve/<category>/<product>/<CVE-ID>/ but there is no structured index. External vulnerability databases (e.g. vulnerability-lookup) cannot discover which CVEs we cover without parsing our taxonomy tree. The taxonomy is fine for authors, wrong for machines.

Goal

Emit a flat, auto-generated, validated manifest.json at a stable public URL so any consumer can answer "does range42 have a hands-on lab for CVE-XXXX-YYYY?" with a single HTTP GET.

Proposed design

1. Per-exercise source-of-truth: exercise.yml

Co-located with every CVE-*/ directory. Field names reuse the CTFd challenge.yml spec where semantically aligned, extended with CVE/CWE/CPE arrays:

schema_version: 1
id: cve-2021-42013-apache
cve: [CVE-2021-42013]
cwe: [CWE-22]
cpe: ["cpe:2.3:a:apache:http_server:2.4.49:*:*:*:*:*:*:*"]
product: apache
category: web
title: "Apache HTTPD Path Traversal + RCE"
description: "..."
exercise_type: docker-compose   # docker-compose|dockerfile|lxc|vm|static
difficulty: intermediate         # beginner|intermediate|advanced
stack: [apache, cgi, bash]
path: 03_container_layer/docker/_ctf/cve/web/apache/CVE-2021-42013
license: GPL-3.0-or-later
authors: ["..."]
tags: [path-traversal, rce]
has_solution: true
solution_path: poc/
estimated_time_minutes: 45
setup_cmd: "make up"
teardown_cmd: "make down"
safety: contained                # contained|requires-isolation
status: active                   # active|deprecated
references:
  - url: https://nvd.nist.gov/vuln/detail/CVE-2021-42013
    tags: [technical-description]

2. Aggregated artefacts (CI-built, never hand-edited)

  • /manifest.json — flat array of all entries + top-level {schema_version, generated_at, source_commit}
  • /by-cve/CVE-YYYY-NNNNN.json — per-CVE entry for cheap point lookups
  • /schemas/exercise.schema.json — JSON Schema Draft 2020-12

3. Publication

  • Commit built artefacts back to main in the same PR as the exercise change that triggered them — stable raw URL: https://raw.githubusercontent.com/range42/range42-catalog/main/manifest.json
  • Attach to GitHub Release assets on tagged versions (immutable snapshot)
  • Optional future: enable GitHub Pages for a CORS-friendly https://range42.github.io/range42-catalog/manifest.json if/when consumers request it

4. Automation (.github/workflows/manifest.yml)

  1. Walk 03_container_layer/docker/_ctf/cve/**/CVE-*/exercise.yml
  2. Validate each against the JSON Schema (ajv-cli or check-jsonschema) — fail build on violation
  3. Aggregate → commit manifest.json + per-CVE files back to the triggering branch
  4. On tag: attach assets to the Release

5. Optional feeder client

Ship tools/range42-sighting/ following the ExploitDBSighting pattern so operators can POST sightings to their own vulnerability-lookup instance without waiting for upstream feeder support.

Non-goals

  • Restructuring the existing taxonomy tree (authors keep category/product/CVE layout; the flat index is a sibling artefact, not a replacement)
  • Defining a new standard — we align with CTFd + CVE 5.0 reference vocabulary

Prior art confirming the gap

Vulhub, trickest/cve, VulnerableApps, VWAD — none publishes a structured CVE manifest. This sets a small convention that external consumers can ingest today.

Acceptance criteria

  • schemas/exercise.schema.json committed and documented in README
  • exercise.yml template added under cve/blank_template/
  • All 14 existing CVE dirs have exercise.yml
  • CI workflow builds + validates + commits manifest.json on every push to main
  • Tagged releases attach manifest.json as an asset
  • tools/range42-sighting/ client can POST to a configured vulnerability-lookup instance
  • README documents the public raw URL + schema location

Related

Companion feature request in vulnerability-lookup will consume this manifest — vulnerability-lookup/vulnerability-lookup#369

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions