// Legacy [`Oracle::OutputContains`] is intentionally retained for // pre-Phase-06 corpus entries until they migrate to // [`Oracle::SinkProbe`]. The deprecation warning is informational, not a // signal to migrate inside this module. #![allow(deprecated)] //! Per-capability payload corpus. //! //! Each [`Cap`] maps to a small set of canonical payloads plus a matching //! detection oracle. Payloads are static data — adding a new one is a code //! review, not a runtime config knob, so they cannot drift between versions. //! //! Differential confirmation (§4.1): for `HTML_ESCAPE` and `FILE_IO`, a //! mandatory benign payload is included. `Confirmed` requires the vuln oracle //! to fire AND the benign oracle NOT to fire. This prevents false-positives //! from coincidental output matches. //! //! # Corpus governance (§16.1) //! //! Every payload carries [`PayloadProvenance`], a [`since_corpus_version`], //! and at least one [`fixture_paths`] entry. The [`CORPUS_VERSION`] const //! tracks the history of incompatible corpus changes; bumping it invalidates //! all `dynamic_verdict_cache` entries whose spec touched the changed cap. use crate::dynamic::oracle::{ProbePredicate, SignalSet}; use crate::labels::Cap; /// Re-exported canonical [`Oracle`] type. /// /// The actual enum lives in [`crate::dynamic::oracle`] alongside /// [`crate::dynamic::oracle::ProbePredicate`] and /// [`crate::dynamic::oracle::oracle_fired`]. Re-exported here so the /// `CuratedPayload.oracle: Oracle` field reads naturally and existing /// `crate::dynamic::corpus::Oracle` callers keep working. pub use crate::dynamic::oracle::Oracle; /// Bump when the corpus content changes in a way that invalidates previously- /// computed [`crate::dynamic::spec::HarnessSpec::spec_hash`] values. /// /// # Bump history /// /// | Version | Date | Change | /// |---------|------------|-----------------------------------------------| /// | 1 | 2025-11-01 | Initial corpus (SQLi, CMDI, PATH_TRAV, SSRF, XSS) | /// | 2 | 2025-12-15 | SSRF OOB-variant added; oracle semantics tightened | /// | 3 | 2026-05-12 | Migrated to `CuratedPayload`; provenance + fixture_paths enforced; SSRF OOB-nonce slot added | /// | 4 | 2026-05-14 | Phase 07: `benign_control` paired refs + benign payloads added to SQLI / CMDI / SSRF (file-scheme) | /// | 5 | 2026-05-16 | FMT_STRING SinkCrash payload + benign control (Phase 08 unrelated-crash acceptance fixture) | pub const CORPUS_VERSION: u32 = 5; /// Where a payload originated. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PayloadProvenance { /// Manually written and reviewed by the Nyx team. Curated, /// Produced by the internal mutation fuzzer (`fuzz/dynamic_corpus/`). /// Still requires human promotion review (§16.4) before landing here. InternalFuzzer, /// Derived from a public CVE or external security report. ExternalReport, } /// Reference from a vulnerable payload to its paired benign control. /// /// Resolved at call time by scanning the same cap's payload slice for an /// `is_benign == true` entry whose `label` matches. Stored as `&'static /// str` (rather than a back-pointer to [`CuratedPayload`]) so the corpus /// tables stay `const`-declarable. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PayloadRef { /// Label of the benign-control entry inside the same cap's payload set. pub label: &'static str, } /// A single payload entry in the curated corpus. /// /// Governs both static payload bytes (or an OOB-nonce template) and the /// oracle used to confirm the vulnerability fired. All fields are /// `'static` so the corpus can live in read-only memory. #[derive(Debug, Clone)] pub struct CuratedPayload { /// Bytes injected into the [`crate::dynamic::spec::PayloadSlot`]. /// /// When [`oob_nonce_slot`] is `true` this field is ignored; the runner /// materialises the actual bytes from the OOB listener URL at call time. pub bytes: &'static [u8], /// Human label for logs and reports. pub label: &'static str, /// How we decide the sink fired. See [`Oracle`]. pub oracle: Oracle, /// If `true`, this is a benign control payload. /// `Confirmed` requires the vuln payload to trigger AND the benign payload /// NOT to trigger (differential confirmation, §4.1). pub is_benign: bool, /// Where this payload came from. pub provenance: PayloadProvenance, /// `CORPUS_VERSION` when this payload was added. pub since_corpus_version: u32, /// `CORPUS_VERSION` at which this payload was deprecated, if any. pub deprecated_at_corpus_version: Option, /// Source files that exercise this payload in the dynamic harness. /// At least one entry required per §16.1. pub fixture_paths: &'static [&'static str], /// When `true`, the runner generates the actual bytes from the OOB /// listener URL + per-finding nonce at execution time (SSRF OOB variant). /// The `bytes` field is unused for such payloads. pub oob_nonce_slot: bool, /// Structured-oracle predicates evaluated against /// [`crate::dynamic::probe::SinkProbe`] records drained from the run's /// probe channel (Phase 06 — Track C.1). Always populated; empty when /// the payload still relies on the legacy /// [`Oracle::OutputContains`](crate::dynamic::oracle::Oracle::OutputContains) /// path and has not been migrated to /// [`Oracle::SinkProbe`](crate::dynamic::oracle::Oracle::SinkProbe) yet. pub probe_predicates: &'static [ProbePredicate], /// Paired benign-control payload inside the same cap's slice. /// /// `Some(PayloadRef)` on a vulnerable entry means the differential rule /// (Phase 07, §4.1) compares this entry's oracle firing against the /// referenced benign. `None` marks the entry as having no paired /// control — the runner downgrades any would-be `Confirmed` to /// [`crate::evidence::InconclusiveReason::NoBenignControl`]. /// Always `None` on benign entries themselves. pub benign_control: Option, } /// Backward-compatible type alias. pub type Payload = CuratedPayload; /// Pick the payload set for a given cap. Empty slice = unsupported cap. /// /// # Cap coverage (update when adding/removing Cap bits) /// /// | Cap | Supported | Notes | /// |--------------------|-----------|-----------------------------------| /// | SQL_QUERY | yes | SQLI payloads (echo-query style) | /// | CODE_EXEC | yes | command injection echo marker | /// | FILE_IO | yes | path traversal + benign control | /// | SSRF | yes | file:// scheme + OOB nonce slot | /// | HTML_ESCAPE | yes | XSS script marker + benign control | /// | FMT_STRING | yes | SinkCrash + benign control (Phase 08) | /// | ENV_VAR | no | source-only cap; no sink oracle | /// | SHELL_ESCAPE | no | sanitizer cap; no sink oracle | /// | URL_ENCODE | no | sanitizer cap; no sink oracle | /// | JSON_PARSE | no | no reliable oracle | /// | DESERIALIZE | no | no reliable oracle | /// | CRYPTO | no | no reliable oracle | /// | UNAUTHORIZED_ID | no | auth bypass; no oracle | /// | DATA_EXFIL | no | exfil; no oracle | /// | LDAP_INJECTION | no | no oracle | /// | XPATH_INJECTION | no | no oracle | /// | HEADER_INJECTION | no | no oracle | /// | OPEN_REDIRECT | no | no oracle | /// | SSTI | no | no oracle | /// | XXE | no | no oracle | /// | PROTOTYPE_POLLUTION| no | JS-runtime; no oracle | /// /// Compile-time exhaustiveness guard: `CORPUS_SUPPORTED | CORPUS_UNSUPPORTED` /// must equal `Cap::all()`. const CORPUS_SUPPORTED: u32 = Cap::SQL_QUERY.bits() | Cap::CODE_EXEC.bits() | Cap::FILE_IO.bits() | Cap::SSRF.bits() | Cap::HTML_ESCAPE.bits() | Cap::FMT_STRING.bits(); const CORPUS_UNSUPPORTED: u32 = Cap::ENV_VAR.bits() | Cap::SHELL_ESCAPE.bits() | Cap::URL_ENCODE.bits() | Cap::JSON_PARSE.bits() | Cap::DESERIALIZE.bits() | Cap::CRYPTO.bits() | Cap::UNAUTHORIZED_ID.bits() | Cap::DATA_EXFIL.bits() | Cap::LDAP_INJECTION.bits() | Cap::XPATH_INJECTION.bits() | Cap::HEADER_INJECTION.bits() | Cap::OPEN_REDIRECT.bits() | Cap::SSTI.bits() | Cap::XXE.bits() | Cap::PROTOTYPE_POLLUTION.bits(); const _: () = assert!( CORPUS_SUPPORTED | CORPUS_UNSUPPORTED == Cap::all().bits(), "Cap bit missing from corpus coverage table; \ add to CORPUS_SUPPORTED or CORPUS_UNSUPPORTED and update payloads_for", ); pub fn payloads_for(cap: Cap) -> &'static [CuratedPayload] { if cap.contains(Cap::SQL_QUERY) { return SQLI; } if cap.contains(Cap::CODE_EXEC) { return CMDI; } if cap.contains(Cap::FILE_IO) { return PATH_TRAV; } if cap.contains(Cap::SSRF) { return SSRF_PAYLOADS; } if cap.contains(Cap::HTML_ESCAPE) { return XSS; } if cap.contains(Cap::FMT_STRING) { return FMT_STRING; } &[] } /// Return the benign control payload for a cap, if one exists. pub fn benign_payload_for(cap: Cap) -> Option<&'static CuratedPayload> { payloads_for(cap).iter().find(|p| p.is_benign) } /// Resolve a [`CuratedPayload::benign_control`] reference to the matching /// benign entry inside the same cap's payload slice. /// /// Returns `None` when the vulnerable payload has no paired control /// (`benign_control == None`) or when the named label is missing / /// non-benign in the corpus. The runner treats the `None` result as /// `NoControl` and downgrades the verdict to /// [`crate::evidence::InconclusiveReason::NoBenignControl`]. pub fn resolve_benign_control( vuln_payload: &CuratedPayload, cap: Cap, ) -> Option<&'static CuratedPayload> { let r = vuln_payload.benign_control?; payloads_for(cap) .iter() .find(|p| p.is_benign && p.label == r.label) } /// Materialise the effective bytes for a payload. /// /// For static payloads (`oob_nonce_slot == false`) returns the `bytes` slice /// directly. For OOB-nonce payloads, constructs the callback URL from the /// listener and nonce; returns `None` when no listener is configured. pub fn materialise_bytes<'a>( payload: &'a CuratedPayload, oob_url: Option<&str>, ) -> Option> { if payload.oob_nonce_slot { oob_url.map(|u| std::borrow::Cow::Owned(u.as_bytes().to_vec())) } else { Some(std::borrow::Cow::Borrowed(payload.bytes)) } } /// Run a marker-collision audit on all corpus payloads. /// /// Returns a list of `(cap_name, label, conflicting_cap_name)` triples where /// a payload's oracle marker string also appears in a different cap's payload /// bytes. An empty result is the expected (passing) state. pub fn audit_marker_collisions() -> Vec<(&'static str, &'static str, &'static str)> { // Build (cap_name, label, marker_bytes) triples for OutputContains oracles. let entries: &[(&str, &[CuratedPayload])] = &[ ("SQL_QUERY", SQLI), ("CODE_EXEC", CMDI), ("FILE_IO", PATH_TRAV), ("SSRF", SSRF_PAYLOADS), ("HTML_ESCAPE", XSS), ]; let mut collisions = Vec::new(); for &(cap_name, payloads) in entries { for p in payloads { if p.is_benign { continue; } let Oracle::OutputContains(marker) = &p.oracle else { continue; }; let marker_bytes = marker.as_bytes(); // Check if this marker appears in ANY other cap's payload bytes. for &(other_cap, other_payloads) in entries { if other_cap == cap_name { continue; } for op in other_payloads { if op.is_benign { continue; } if op.bytes.windows(marker_bytes.len()).any(|w| w == marker_bytes) { collisions.push((cap_name, p.label, other_cap)); } } } } } collisions } #[cfg(test)] mod tests { use super::*; #[test] fn supported_caps_have_payloads() { assert!(!payloads_for(Cap::SQL_QUERY).is_empty()); assert!(!payloads_for(Cap::CODE_EXEC).is_empty()); assert!(!payloads_for(Cap::FILE_IO).is_empty()); assert!(!payloads_for(Cap::SSRF).is_empty()); assert!(!payloads_for(Cap::HTML_ESCAPE).is_empty()); assert!(!payloads_for(Cap::FMT_STRING).is_empty()); } #[test] fn unsupported_caps_return_empty() { let unsupported = [ Cap::ENV_VAR, Cap::SHELL_ESCAPE, Cap::URL_ENCODE, Cap::JSON_PARSE, Cap::DESERIALIZE, Cap::CRYPTO, Cap::UNAUTHORIZED_ID, Cap::DATA_EXFIL, Cap::LDAP_INJECTION, Cap::XPATH_INJECTION, Cap::HEADER_INJECTION, Cap::OPEN_REDIRECT, Cap::SSTI, Cap::XXE, Cap::PROTOTYPE_POLLUTION, ]; for cap in unsupported { assert!( payloads_for(cap).is_empty(), "expected {cap:?} to return empty payloads", ); } } #[test] fn fileio_has_benign_payload() { assert!(benign_payload_for(Cap::FILE_IO).is_some()); } #[test] fn html_escape_has_benign_payload() { assert!(benign_payload_for(Cap::HTML_ESCAPE).is_some()); } #[test] fn vuln_payloads_not_benign() { for cap in [ Cap::SQL_QUERY, Cap::CODE_EXEC, Cap::FILE_IO, Cap::HTML_ESCAPE, Cap::FMT_STRING, ] { let has_vuln = payloads_for(cap).iter().any(|p| !p.is_benign); assert!(has_vuln, "{cap:?} must have at least one vuln (non-benign) payload"); } } #[test] fn fmt_string_has_sink_crash_oracle_and_benign_control() { let payloads = payloads_for(Cap::FMT_STRING); let vuln = payloads .iter() .find(|p| !p.is_benign) .expect("FMT_STRING must have a vuln payload"); assert!( matches!(vuln.oracle, Oracle::SinkCrash { .. }), "FMT_STRING vuln payload oracle must be SinkCrash (Phase 08)" ); let bref = vuln .benign_control .expect("FMT_STRING vuln must reference a benign control"); assert!( resolve_benign_control(vuln, Cap::FMT_STRING).is_some(), "FMT_STRING benign-control label '{}' must resolve", bref.label, ); } #[test] fn marker_uniqueness_sqli() { for p in SQLI { assert!(!p.bytes.windows(7).any(|w| w == b"NYX_PWN"), "NYX_PWN (CODE_EXEC marker) must not appear in SQLI payloads"); } } #[test] fn all_payloads_have_fixture_paths() { let caps = [ Cap::SQL_QUERY, Cap::CODE_EXEC, Cap::FILE_IO, Cap::SSRF, Cap::HTML_ESCAPE, Cap::FMT_STRING, ]; for cap in caps { for p in payloads_for(cap) { assert!( !p.fixture_paths.is_empty(), "payload '{}' for {cap:?} must have at least one fixture_path (§16.1)", p.label, ); } } } #[test] fn all_payloads_have_valid_since_corpus_version() { let caps = [ Cap::SQL_QUERY, Cap::CODE_EXEC, Cap::FILE_IO, Cap::SSRF, Cap::HTML_ESCAPE, Cap::FMT_STRING, ]; for cap in caps { for p in payloads_for(cap) { assert!( p.since_corpus_version >= 1 && p.since_corpus_version <= CORPUS_VERSION, "payload '{}': since_corpus_version {} out of range [1, {}]", p.label, p.since_corpus_version, CORPUS_VERSION, ); } } } #[test] fn no_marker_collisions() { let collisions = audit_marker_collisions(); assert!( collisions.is_empty(), "marker collisions detected (§16.3): {collisions:?}", ); } #[test] fn ssrf_has_oob_nonce_slot() { let has_oob = payloads_for(Cap::SSRF).iter().any(|p| p.oob_nonce_slot); assert!(has_oob, "SSRF corpus must include an OOB-nonce-slot payload"); } #[test] fn materialise_static_payload() { let p = &SQLI[0]; assert!(!p.oob_nonce_slot); let bytes = materialise_bytes(p, None).expect("static payload must materialise without OOB"); assert_eq!(&*bytes, p.bytes); } #[test] fn materialise_oob_payload_with_url() { let p = SSRF_PAYLOADS.iter().find(|p| p.oob_nonce_slot).expect("must have OOB payload"); let url = "http://127.0.0.1:54321/mynonce"; let bytes = materialise_bytes(p, Some(url)).expect("OOB payload materialises with URL"); assert_eq!(&*bytes, url.as_bytes()); } #[test] fn materialise_oob_payload_without_listener_returns_none() { let p = SSRF_PAYLOADS.iter().find(|p| p.oob_nonce_slot).expect("must have OOB payload"); assert!(materialise_bytes(p, None).is_none(), "no OOB URL → None"); } #[test] fn benign_control_refs_resolve_for_paired_caps() { let cases: &[(Cap, &str, &str)] = &[ (Cap::SQL_QUERY, "sqli-tautology", "sqli-benign"), (Cap::SQL_QUERY, "sqli-union-nyx", "sqli-benign"), (Cap::CODE_EXEC, "cmdi-echo-marker", "cmdi-benign"), (Cap::FILE_IO, "path-traversal-passwd", "path-traversal-benign"), (Cap::SSRF, "ssrf-file-scheme", "ssrf-benign"), (Cap::HTML_ESCAPE, "xss-script-marker", "xss-benign-text"), ]; for (cap, vuln_label, benign_label) in cases { let vuln = payloads_for(*cap) .iter() .find(|p| p.label == *vuln_label) .unwrap_or_else(|| panic!("missing vuln payload {vuln_label} for {cap:?}")); let resolved = resolve_benign_control(vuln, *cap) .unwrap_or_else(|| panic!("missing benign control for {vuln_label}")); assert_eq!(resolved.label, *benign_label); assert!(resolved.is_benign, "resolved control must be marked benign"); } } #[test] fn oob_payload_has_no_benign_control() { let p = SSRF_PAYLOADS .iter() .find(|p| p.oob_nonce_slot) .expect("OOB payload"); assert!(p.benign_control.is_none(), "OOB-nonce payload is intentionally NoControl"); assert!(resolve_benign_control(p, Cap::SSRF).is_none()); } #[test] fn benign_entries_are_terminal() { let caps = [ Cap::SQL_QUERY, Cap::CODE_EXEC, Cap::FILE_IO, Cap::SSRF, Cap::HTML_ESCAPE, Cap::FMT_STRING, ]; for cap in caps { for p in payloads_for(cap).iter().filter(|p| p.is_benign) { assert!( p.benign_control.is_none(), "benign payload {} must not chain to another control", p.label, ); } } } } // ── SQLi ───────────────────────────────────────────────────────────────────── // Payloads designed to cause the target code to echo a query containing "NYX". // Fixtures should print the raw query or error message to stdout/stderr. const SQLI: &[CuratedPayload] = &[ CuratedPayload { bytes: b"' OR '1'='1", label: "sqli-tautology", oracle: Oracle::OutputContains("NYX_SQL_CONFIRMED"), is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/sqli/sqli_rusqlite_format.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: Some(PayloadRef { label: "sqli-benign" }), }, CuratedPayload { bytes: b"' UNION SELECT 'NYX_SQL_CONFIRMED'--", label: "sqli-union-nyx", oracle: Oracle::OutputContains("NYX_SQL_CONFIRMED"), is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/sqli/sqli_rusqlite_format.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: Some(PayloadRef { label: "sqli-benign" }), }, // Benign control: ordinary value that should never produce the SQL marker. CuratedPayload { bytes: b"benign_safe_sqli_NYX_BENIGN", label: "sqli-benign", oracle: Oracle::OutputContains("NYX_SQL_CONFIRMED"), is_benign: true, provenance: PayloadProvenance::Curated, since_corpus_version: 4, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/sqli/sqli_rusqlite_format.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: None, }, ]; // ── Command injection ───────────────────────────────────────────────────────── const CMDI: &[CuratedPayload] = &[ CuratedPayload { bytes: b"; echo NYX_PWN_CMDI", label: "cmdi-echo-marker", oracle: Oracle::OutputContains("NYX_PWN_CMDI"), is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &[ "tests/benchmark/corpus/rust/cmdi/cmdi_command.rs", "tests/benchmark/corpus/rust/cmdi/cmdi_args.rs", ], oob_nonce_slot: false, probe_predicates: &[], benign_control: Some(PayloadRef { label: "cmdi-benign" }), }, // Benign control: plain text that should never produce the cmdi marker. CuratedPayload { bytes: b"benign_safe_cmdi_NYX_BENIGN", label: "cmdi-benign", oracle: Oracle::OutputContains("NYX_PWN_CMDI"), is_benign: true, provenance: PayloadProvenance::Curated, since_corpus_version: 4, deprecated_at_corpus_version: None, fixture_paths: &[ "tests/benchmark/corpus/rust/cmdi/cmdi_command.rs", "tests/benchmark/corpus/rust/cmdi/cmdi_args.rs", ], oob_nonce_slot: false, probe_predicates: &[], benign_control: None, }, ]; // ── Path traversal ──────────────────────────────────────────────────────────── // Benign payload reads a known-safe file (Python's os module source path). // Differential confirmation: vuln fires on /etc/passwd; benign fires on a // non-sensitive file and must NOT fire the same oracle (different file content). const PATH_TRAV: &[CuratedPayload] = &[ CuratedPayload { bytes: b"../../../../etc/passwd", label: "path-traversal-passwd", oracle: Oracle::OutputContains("root:"), is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &[ "tests/benchmark/corpus/rust/path_traversal/path_file_open.rs", "tests/benchmark/corpus/rust/path_traversal/path_read.rs", ], oob_nonce_slot: false, probe_predicates: &[], benign_control: Some(PayloadRef { label: "path-traversal-benign" }), }, CuratedPayload { bytes: b"benign_safe_file_that_does_not_exist_NYX_BENIGN", label: "path-traversal-benign", oracle: Oracle::OutputContains("root:"), is_benign: true, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/path_traversal/path_file_open.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: None, }, ]; // ── SSRF ───────────────────────────────────────────────────────────────────── // Two SSRF variants: // 1. file:// scheme — static payload, OutputContains oracle. Works in // the process backend without OOB infrastructure. // 2. OOB nonce slot — URL generated at runtime from the OOB listener. // Confirms SSRF by recording the callback nonce. // // Oracle notes: // OutputContains("daemon:") matches both Linux (`daemon:x:1:1:`) and // macOS (`daemon:*:1:1:`) /etc/passwd formats and must NOT collide with // FILE_IO's "root:" marker (see marker_uniqueness test). const SSRF_PAYLOADS: &[CuratedPayload] = &[ CuratedPayload { bytes: b"file:///etc/passwd", label: "ssrf-file-scheme", oracle: Oracle::OutputContains("daemon:"), is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/ssrf/ssrf_reqwest.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: Some(PayloadRef { label: "ssrf-benign" }), }, CuratedPayload { // `bytes` is unused when `oob_nonce_slot = true`; the runner // materialises the URL from the OOB listener at call time. bytes: b"", label: "ssrf-oob-nonce", oracle: Oracle::OobCallback { host: "127.0.0.1" }, is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 2, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/ssrf/ssrf_reqwest.rs"], oob_nonce_slot: true, probe_predicates: &[], // OOB-nonce payloads are self-confirming via the listener; no // benign counterpart is meaningful (a benign URL can never hit // the nonce listener), so this entry sits at `NoControl`. benign_control: None, }, // Benign control for the file-scheme SSRF variant. Fetched the same // way as the vuln payload but cannot resolve to a body containing the // `daemon:` marker. CuratedPayload { bytes: b"benign_safe_ssrf_NYX_BENIGN", label: "ssrf-benign", oracle: Oracle::OutputContains("daemon:"), is_benign: true, provenance: PayloadProvenance::Curated, since_corpus_version: 4, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/ssrf/ssrf_reqwest.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: None, }, ]; // ── XSS ────────────────────────────────────────────────────────────────────── // Vuln: raw script tag echoed to output. // Benign: harmless text that should NOT produce the XSS marker. const XSS: &[CuratedPayload] = &[ CuratedPayload { bytes: b"", label: "xss-script-marker", oracle: Oracle::OutputContains(""), is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/xss/axum_html/main.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: Some(PayloadRef { label: "xss-benign-text" }), }, CuratedPayload { bytes: b"Hello World", label: "xss-benign-text", oracle: Oracle::OutputContains(""), is_benign: true, provenance: PayloadProvenance::Curated, since_corpus_version: 1, deprecated_at_corpus_version: None, fixture_paths: &["tests/benchmark/corpus/rust/xss/axum_html/main.rs"], oob_nonce_slot: false, probe_predicates: &[], benign_control: None, }, ]; // ── Format string (Phase 08 SinkCrash variant) ──────────────────────────────── // The vuln payload confirms via a sink-site Crash probe rather than an // output marker. The bytes themselves are not load-bearing — the // detection contract is "process aborts inside the entry call AFTER the // crash-guard installs". Fixtures choose how to crash on the payload; // the canonical example is a printf-family sink that interprets `%n` // against a controlled destination pointer on a guard-compiled binary. // // The benign control must reach the same entry without crashing; its // bytes carry `NYX_BENIGN` so fixture code can short-circuit before // the fault path. const FMT_STRING: &[CuratedPayload] = &[ CuratedPayload { bytes: b"%n%n%n%n%n%n%n%n%n%n", label: "fmt-string-percent-n-crash", oracle: Oracle::SinkCrash { signals: SignalSet::all(), }, is_benign: false, provenance: PayloadProvenance::Curated, since_corpus_version: 5, deprecated_at_corpus_version: None, fixture_paths: &[ "tests/dynamic_fixtures/c/free_fn/sink_fault.c", "tests/dynamic_fixtures/c/free_fn/setup_fault.c", ], oob_nonce_slot: false, probe_predicates: &[], benign_control: Some(PayloadRef { label: "fmt-string-benign" }), }, CuratedPayload { bytes: b"benign_safe_fmt_NYX_BENIGN", label: "fmt-string-benign", oracle: Oracle::SinkCrash { signals: SignalSet::all(), }, is_benign: true, provenance: PayloadProvenance::Curated, since_corpus_version: 5, deprecated_at_corpus_version: None, fixture_paths: &["tests/dynamic_fixtures/c/free_fn/sink_fault.c"], oob_nonce_slot: false, probe_predicates: &[], benign_control: None, }, ];