Skip to content

Latest commit

ย 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SigCraft

CVE advisories & patch diffs โ†’ candidate Nuclei templates and YARA rules

CI Python 3.11+ MIT License Status: v0

Quickstart ยท How it works ยท Commands ยท Eval harness ยท Contributing


When a CVE drops, detection engineers spend hours reading advisory text and patch diffs to hand-write a detection rule. SigCraft does the mechanical first pass and hands a reviewer something to correct rather than a blank file.

Warning

Every emitted rule is an unreviewed candidate. Nothing here is production-ready out of the box. The validation layer tells you which parts to trust; a human still signs off before deployment.

Quickstart

git clone https://github.com/tal7aouy/sigcraft.git
cd sigcraft
uv pip install -e ".[dev]"

# No API key needed โ€” run the deterministic half against a sample patch
sigcraft inspect --diff examples/path-traversal.diff
   local-diff: path-traversal
   2 diff hunk(s) across 1 file(s)
   6 signal(s): added_guard=2, http_param=1, function=1, file_path=1, binary_string=1
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ signals โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ http_param:                                                              โ”‚
โ”‚   - file     # name := req.URL.Query().Get("file")                       โ”‚
โ”‚ file_path:                                                               โ”‚
โ”‚   - internal/handler/download.go                                         โ”‚
โ”‚ function:                                                                โ”‚
โ”‚   - registerRoutes     # func registerRoutes(r *mux.Router) {            โ”‚
โ”‚ added_guard:                                                             โ”‚
โ”‚   - path-normalisation   # target := filepath.Clean(filepath.Join(...))  โ”‚
โ”‚   - traversal-check      # if !strings.HasPrefix(target, storageRoot...) โ”‚
โ”‚ binary_string:                                                           โ”‚
โ”‚   - read failed:      # present in vulnerable version, removed by patch  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
   nuclei (nuclei 2.7 vs yara 0.5)
          - 1 HTTP-shaped signal(s) extracted
          - 1 literal string(s) recovered from the diff
          - patch touches mostly web-stack code (2 web vs 0 native files)

Every indicator carries the line it came from. That provenance is what the validator later audits the generated rule against.

How it works

An LLM writing YAML is not the product. The validation layer is the product.

Anyone can feed an advisory to a model and get a plausible-looking template. What makes the output usable is knowing which parts to trust. So:

  1. A deterministic extractor mines indicators โ€” paths, params, versions, functions, strings โ€” from the advisory and diff before the model is called.
  2. The model is instructed it may only use indicators traceable to those inputs.
  3. The validator cross-checks the generated rule against the extracted signals. If a template probes a path the extractor never saw, that's flagged as possibly invented.

That cross-check (signal-anchored in both validators) is the differentiator. The extractor is the ground truth the output is audited against, and it is never weakened to make the model's job easier.

Pipeline

ingest โ†’ extract โ†’ route โ†’ generate (LLM) โ†’ validate โ†’ emit
Stage What it does Network API key
ingest NVD, GitHub commits/PRs, GHSA, local diffs yesยน โ€”
extract Deterministic signal mining โ€” โ€”
route Scores nuclei vs yara โ€” โ€”
generate Anthropic structured-output call yes yes
validate 3 layers: structure / semantics / engine โ€” โ€”
emit Provenance header + file write โ€” โ€”
eval Corpus scoring โ€” โ€”

ยน Not needed with --diff.

Only generate needs a key. inspect, check, eval, and gen --dry-run run the entire deterministic half without one โ€” that's how you develop and demo this without spending tokens.

Validation layers

Both validators run cheapest-first, and each layer is independently callable:

Layer Catches
structure Doesn't parse, missing required fields, bad severity
semantics Status-code-only matchers, generic words (error, admin), missing matchers-condition: and, YARA strings under 6 bytes, any of them with many strings, missing filesize/magic guard, invented indicators
engine Real nuclei -validate / yara compile

Findings are pass / warn / fail. A missing binary is always a warn, never a fail โ€” absent tooling says nothing about a rule's quality.

Install

Requires Python 3.11+. uv recommended.

uv pip install -e ".[dev]"

Optional extras:

uv pip install -e ".[yara]"   # yara-python, enables YARA compile-check

External validators are auto-detected and optional:

  • nuclei โ€” engine validation for templates
  • yara CLI or yara-python โ€” compile-check for rules

Run sigcraft version to see what's available.

Commands

# Deterministic half โ€” no API key needed
sigcraft inspect --cve CVE-2023-4966
sigcraft inspect --diff examples/path-traversal.diff
sigcraft inspect --commit https://github.com/o/r/commit/SHA --show-prompt

# Generate a candidate rule (needs ANTHROPIC_API_KEY)
sigcraft gen --cve CVE-2024-1234 --target auto -o out/
sigcraft gen --cve CVE-2024-1234 --dry-run          # everything except the model call

# Batch triage a whole list of CVEs (Patch Tuesday)
sigcraft gen --from-file cves.txt --dry-run         # no key needed
sigcraft gen --from-file cves.txt --concurrency 4 -o out/

# Score the pipeline against known-good rules
sigcraft eval
sigcraft eval --generated out/ --verbose
sigcraft eval --json

# Validate any existing rule file
sigcraft check out/cve-2024-1234.yaml

sigcraft version

Exit codes: 0 ok ยท 1 error ยท 2 validation failed (the rule is still written so you can inspect it). eval exits 1 if routing accuracy falls below --min-routing or a known-good reference rule fails validator alignment.

Evaluation harness

sigcraft eval scores the deterministic pipeline against a corpus of CVEs with known-good published rules โ€” no model call, no key. It turns extractor/router/prompt tuning from vibes into measurement.

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ eval: 5 case(s) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ case                          target  route  recall  align   sim         โ”‚
โ”‚ cve-2023-4966-citrix-bleed    nuclei   ok      0.33   ok    skip         โ”‚
โ”‚ cve-2024-3389-use-after-free  yara     ok      1.00   ok    skip         โ”‚
โ”‚ cve-2024-5561-path-traversal  nuclei   ok      0.67   ok    skip         โ”‚
โ”‚ cve-2024-7780-heap-overflow   yara     ok      1.00   ok    skip         โ”‚
โ”‚ cve-2024-9020-reflected-xss   nuclei   ok      0.50   ok    skip         โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
  routing accuracy: 1.00   mean recall: 0.70   alignment failures: 0

Three scores, each independently meaningful:

  • routing accuracy โ€” did the router pick the engine the reference rule is written for?
  • extraction recall โ€” of the indicators the reference rule actually uses, how many did the extractor surface? Misses are reported as missing rather than collapsed to zero, because an indicator may simply not be present in the inputs โ€” that's not an extractor gap. Read the missing list to tell them apart.
  • validator alignment โ€” does our validator accept the known-good rule? A hard fail is either a validator bug or a low-quality reference; both are worth surfacing.

generation-similarity is only computable once gen has run against a real key, so it reports skipped unless --generated is passed โ€” a keyless run can't be misread as "0% similar".

Add a case by dropping a directory in eval/corpus/ containing case.yaml, a reference.yaml/reference.yar, and an optional *.diff. No registration needed. Because the corpus is offline and deterministic, a score regression is a code regression โ€” not a flaky API.

Project layout

sigcraft/
โ”œโ”€โ”€ models.py            # Pydantic domain model, shared by every stage
โ”œโ”€โ”€ cli.py               # gen / inspect / check / eval / version
โ”œโ”€โ”€ route.py             # nuclei-vs-yara scoring
โ”œโ”€โ”€ emit.py              # provenance header + file writing
โ”œโ”€โ”€ ingest/              # NVD ยท GitHub ยท GHSA ยท unified-diff parser
โ”œโ”€โ”€ extract/signals.py   # all deterministic signal mining
โ”œโ”€โ”€ llm/client.py        # Anthropic call, structured output
โ””โ”€โ”€ validate/            # nuclei_check.py ยท yara_check.py
eval/                    # corpus loading, metrics, runner
prompts/                 # nuclei.md, yara.md โ€” tune without touching code
examples/                # fixture diffs (web + native) for testing routing

Detection guidance lives in prompts/*.md and is loaded at runtime โ€” tune it there rather than inlining prompt text into Python.

Environment

Variable Required Purpose
ANTHROPIC_API_KEY for gen only Model access
NVD_API_KEY optional Raises NVD rate limit
GITHUB_TOKEN optional Raises GitHub rate limit

Contributing

Contributions are welcome. Start with CONTRIBUTING.md โ€” it covers the dev setup, the invariants that must not be broken, and how to add extraction patterns or eval cases safely.

By participating you agree to the Code of Conduct. To report a vulnerability, see SECURITY.md.

License

MIT

About

๐Ÿ›ก๏ธ Turn CVE advisories and patch diffs into candidate Nuclei templates and YARA rules โ€” with a validation layer that flags invented indicators.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages