Skip to content

v0.23.0

Choose a tag to compare

@mostafa mostafa released this 30 Sep 14:15
· 173 commits to main since this release
6993d62

TL;DR
RSigma v0.23.0 is the "threat intel in the loop" release: rsigma can now pull STIX 2.1 threat intel from TAXII servers or bundle files into a local store and enrich live detections from it, fieldref gains string comparisons with pySigma-compatible |neq, and two MCP server vulnerabilities are fixed.

  • Security: the MCP server now confines every path argument to --rules-dir (GHSA-8x2w-m5v2-phxr) and evaluate_events refuses command and http enrichers (GHSA-4q23-jm32-fhr9). Upgrade if you run rsigma mcp serve.
  • Threat intel: taxii sync (#508) and taxii store (#509) import into a local store with validate-on-ingest (#499), the stix enricher and engine daemon --stix-store enrich detections from it (#509), and paginated ingest is tested at ATT&CK scale (#507) (thanks to @SecurityEnthusiast).
  • Detection correctness: fieldref with contains, startswith, and endswith, and |neq now negates the whole detection item as pySigma does (#506, thanks to @Karib0u).
  • Agents: an installable agent skill for the CLI and MCP loop (#501).
  • Breaking: build_enrichers_full takes EnricherResources (#509), rstix ingest_collection returns IngestReport (#499), the HIR cache schema is 2 (#506), and MCP evaluate_events only accepts template enrichers.
  • Dependencies: rustls 0.23.45 for RUSTSEC-2026-0285 (#498, thanks to @SecurityEnthusiast) and Dependabot batches across Rust, CI, the VS Code extension, and docs (#491, #512).

rsigma-mcp: enforce --rules-dir confinement and refuse process and network enrichers (security)

Fixes GHSA-8x2w-m5v2-phxr and GHSA-4q23-jm32-fhr9. With --rules-dir set, parse_rule, lint_rules, fix_rules, evaluate_events, list_fields, validate_rules, author_ads, resolve_pipeline, and convert_rules accepted absolute and ../ paths outside the directory, so an MCP caller could read any file the server's OS user could read, and fix_rules with write: true could rewrite files outside it.

  • Every path argument (path, events_path, enrichers_path, and file-based pipelines) is now canonicalized and refused if it leaves --rules-dir. A missing file outside the root fails the same way as an existing one. Directory inputs containing a symlink are refused, matching tune_rules.
  • evaluate_events now builds only template enrichers (GHSA-4q23-jm32-fhr9). Inline command enrichers ran arbitrary local programs and http enrichers reached arbitrary network endpoints as the server process; both are refused, along with lookup and stix. Configure them on the daemon.
  • Delegated convert_rules passes only bare identifiers through as sigma-cli pipeline names and runs sigma-cli from the rules root, so a relative pipeline path can no longer resolve against the server's working directory.

Dependency batch (late Sep 2026) (#512)

Rolls up the open Dependabot PRs into a single merge, with Cargo.lock regenerated against current main. Rust: jsonschema 0.48.5 to 0.56.0 (#497, also moving fancy-regex 0.18.0 to 0.19.2 and fraction 0.15.4 to 0.17.0) and dirs 6.0.0 to 7.0.0 (#496). CI (all repinned by commit SHA, batched via the actions-updates group, #504): taiki-e/install-action v2.87.4 to v2.87.14, docker/setup-buildx-action v4.3.0 to v4.4.1, docker/build-push-action v7.3.0 to v7.4.0, github/codeql-action/upload-sarif v4.37.9 to v4.38.0, and zizmorcore/zizmor-action v0.6.3 to v0.6.4. VS Code extension: @types/node 26.5.1 to 26.6.1 and @types/vscode 1.137.0 to 1.138.0 (#502), @vscode/vsce 3.9.2 to 4.0.0 (#503), and the brace-expansion override 5.0.9 to 5.0.12 (#510). Docs: markdown-it 14.3.0 to 14.3.2 (#511). Held back: yamlpath 1.30.1 (#495) and yamlpatch 1.30.1 (#494) still pull tree-sitter-iter 1.28+ which requires rustc 1.97, above the 1.95.0 MSRV; tikv-jemallocator 0.7.0 (#425, jemalloc 5.3.1) still regresses musl routed daemon throughput about 4-7% versus 0.6.1.

rsigma: taxii store command (#509)

  • New taxii store subcommand (taxii-sync feature): import a local STIX 2.1 bundle JSON file (or stdin via --bundle -) into a local FsStore with the same Validator::producer_strict() validate-on-ingest profile as taxii sync.
  • Supports --allow-custom for MITRE ATT&CK bundles, default --strict, and structured import/validation summary output.

rsigma: STIX store enrichment (stix-enrich feature) (#509)

  • Fifth enricher primitive type: stix: query a local FsStore by stix_id, text_search, or attack_technique (first attack.t* tag) and inject matching objects under enrichments.<field>.
  • engine daemon --stix-store <DIR> (and daemon.stix_store in config): same on-disk layout as taxii sync. Store index reloads from disk on enricher hot-reload after external taxii sync writes.
  • engine daemon --stix-store-allow-custom: load MITRE/custom types from disk (required when the store was populated with --allow-custom).
  • rstix: FsStore::reload_from_disk + MemoryStore::clear for live refresh without reopening the store handle.
  • Public API: EnricherResources + extended build_enrichers_full (breaking vs 0.22.0: third argument is now EnricherResources, not Option<SourceCache>).

rsigma: taxii sync command (#508)

  • New taxii sync subcommand (opt-in taxii-sync feature) imports a TAXII 2.1 collection into a local FsStore with IngestOptions::producer_strict() validate-on-ingest.
  • Supports bearer, basic, and API-key auth, optional mTLS client certificates, discovery-based API root resolution, and structured import/validation summary output.
  • Default --strict: exit code 1 when validation rejects objects; re-sync is idempotent (objects_deduplicated).

rstix: ATT&CK-scale paginated TAXII ingest tests (#507)

  • Synthetic 5 000-object paginated ingest_collection test with IngestOptions::producer_strict() runs in CI (taxii-store + validate).
  • Env-gated RSTIX_ATTCK_BUNDLE corpus test for real MITRE enterprise bundles (allow_custom on TaxiiClient); pinned release enterprise-attack-19.2.json for manual workflow and local corpus path.
  • Optional workflow_dispatch job ATT&CK ingest proof (.github/workflows/attck-ingest.yml); not a PR gate.

Field references with contains, startswith, and endswith (#506)

fieldref may be followed by one of contains, startswith, or endswith. The comparison is case-insensitive unless |cased is also set. A wildcard in the referenced field name is rejected, and a string modifier written before fieldref is rejected. Thanks to @Karib0u, who reported these three combinations in #505.

PostgreSQL renders the substring forms with strpos and right, so % and _ in the referenced value stay literal, and fieldref equality compares lower() of both sides unless |cased is set. Fibratus renders equality with ~= and the substring forms with icontains, istartswith, and iendswith.

|neq now negates the whole detection item, as pySigma does. Field|neq: [a, b] matches when the field is neither a nor b; before, it matched when the field differed from either value. re|neq, cidr|neq, fieldref|neq, and neq with a timestamp part also compiled without the negation before.

|neq now converts. A missing referenced field counts as not equal when the left field is present. PostgreSQL expresses that as (comparison) IS NOT TRUE AND "field" IS NOT NULL. LynxDB negates its deferred where clauses (!~, NOT cidrmatch). Other backends negate the comparison directly.

incompatible_modifiers accepts fieldref followed by one of those string modifiers, and fieldref or a string comparison combined with neq. It warns when a string modifier precedes fieldref, and when fieldref is combined with re, cidr, a numeric comparison, exists, a timestamp part, or an encoding modifier. neq combines with string comparisons as well as with numbers.

FieldRef now carries the string operator. The HIR cache schema is 2, so a cache written by an older build is rejected and recompiled.

Agent skill for the CLI and MCP loop (#501)

skills/rsigma/ teaches agents the current command groups (engine, rule, backend, pipeline, mcp, config) and the write-lint-evaluate-convert loop. Install with npx skills add timescale/rsigma -g -y. Sigma YAML authoring stays in the sigma-rules skill.

rstix: validate-on-ingest for TAXII collections (#499)

Public API (breaking vs 0.22.0):

  • ingest_collection / ingest_collection_with_bundle_id now return IngestReport instead of ImportReport.
  • ingest_collection_with_bundle_id takes a new IngestOptions argument.

With the validate feature, attach IngestOptions::producer_strict() (or a custom Validator) to validate each object before store import; invalid objects are rejected by default (reject_invalid_objects: true). Per-object validation skips the References phase so forward refs across TAXII pages still resolve after the full ingest.

Security: rustls advisory + cargo-deny config (#498)

  • Cargo.lock: bump rustls 0.23.44 → 0.23.45 (RUSTSEC-2026-0285).
  • deny.toml: remove stale RUSTSEC-2021-0153 ignore entry that triggered advisory-not-detected; encoding via evtx remains a workspace unmaintained warning.

Dependency batch (mid Sep 2026) (#491)

Rolls up the open Dependabot PRs into a single merge, regenerated against current main rather than replaying stale lockfile bases. Rust (workspace Cargo.lock, with fuzz/Cargo.lock and ci/wasm-smoke/Cargo.lock synced): the patch group (#487) updates flate2 1.1.9 to 1.1.10, jaq-core 3.1.0 to 3.1.1, jaq-json 2.0.2 to 2.0.3, jaq-std 3.0.2 to 3.0.3, rcgen 0.14.9 to 0.14.10, tower-http 0.7.0 to 0.7.1, hyper 1.11.0 to 1.11.1, hickory-resolver 0.26.1 to 0.26.3 (#487 requested 0.26.2), and toml 1.1.4+spec-1.1.0 to 1.1.6+spec-1.1.0 (#487 requested 1.1.5); standalone updates move tokio 1.52.3 to 1.53.1 (#490) and rmcp 3.0.1 to 3.3.0 (#489 requested 3.2.0). A follow-up cargo update also refreshes rustls 0.23.43 to 0.23.44, uuid 1.24.1 to 1.26.1, cel 0.14.4 to 0.14.5, pest 2.8.8 to 2.9.1, jiff 0.2.31 to 0.2.37, tree-sitter 0.26.10 to 0.26.13, zerocopy 0.8.52 to 0.8.57, and sse-stream 0.2.4 to 0.2.6. CI (all repinned by commit SHA, batched via the actions-updates group, #486): taiki-e/install-action v2.87.0 to v2.87.4, anchore/scan-action v7.4.1 to v7.4.2, actions/deploy-pages v5.0.0 to v5.0.1, and zizmorcore/zizmor-action v0.6.2 to v0.6.3. VS Code extension: @types/node 26.4.0 to 26.4.1 and @types/vscode 1.134.0 to 1.136.0 (#485), then npm update brings the lockfile to @types/node 26.5.1 and @types/vscode 1.137.0. Docs (docs/docmd-plugin-rsigma): sharp 0.35.3 to 0.35.4 for GHSA-rgj7-g3m4-5g8c (libheif RCE in < 0.35.4, Dependabot alert 62). Held back: yamlpatch 1.30.0 (#488) still pulls tree-sitter-iter 1.28+ which requires rustc 1.97, so yamlpath stays at 1.27.0 with yamlpatch 1.26.1; tikv-jemallocator 0.7.0 (#425, jemalloc 5.3.1) still regresses musl routed daemon throughput about 4-7% versus 0.6.1.

v0.22.0...v0.23.0