mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-27 20:29:39 +02:00
[pitboss] phase 07: Track J.5 + Track L.5 — XPATH_INJECTION corpus + XPath / DOM / lxml adapters
This commit is contained in:
parent
b2eeaabb09
commit
a32075a756
38 changed files with 2111 additions and 67 deletions
|
|
@ -20,7 +20,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
bytes: b"alice*)(uid=*",
|
||||
label: "ldap-java-filter-wildcard",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: false,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
|
|
@ -28,7 +28,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/ldap_injection/java/Vuln.java"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
probe_predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
benign_control: Some(PayloadRef {
|
||||
label: "ldap-java-benign",
|
||||
}),
|
||||
|
|
@ -38,7 +38,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
bytes: b"alice",
|
||||
label: "ldap-java-benign",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: true,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
//! intended single user.
|
||||
//!
|
||||
//! The oracle's
|
||||
//! [`crate::dynamic::oracle::ProbePredicate::LdapResultCountGreaterThan`]
|
||||
//! [`crate::dynamic::oracle::ProbePredicate::QueryResultCountGreaterThan`]
|
||||
//! checks the per-payload `ProbeKind::Ldap.entries_returned` against
|
||||
//! `n = 1` — vuln passes (3 entries), benign clears (1 entry),
|
||||
//! fulfilling the §4.1 differential rule.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
bytes: b"alice*)(uid=*",
|
||||
label: "ldap-php-filter-wildcard",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: false,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
|
|
@ -26,7 +26,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/ldap_injection/php/vuln.php"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
probe_predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
benign_control: Some(PayloadRef {
|
||||
label: "ldap-php-benign",
|
||||
}),
|
||||
|
|
@ -36,7 +36,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
bytes: b"alice",
|
||||
label: "ldap-php-benign",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: true,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
bytes: b"alice*)(uid=*",
|
||||
label: "ldap-python-filter-wildcard",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: false,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
|
|
@ -27,7 +27,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/ldap_injection/python/vuln.py"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
probe_predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
benign_control: Some(PayloadRef {
|
||||
label: "ldap-python-benign",
|
||||
}),
|
||||
|
|
@ -37,7 +37,7 @@ pub const PAYLOADS: &[CuratedPayload] = &[
|
|||
bytes: b"alice",
|
||||
label: "ldap-python-benign",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::LdapResultCountGreaterThan { n: 1 }],
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: true,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use super::{cmdi, deserialize, fmt_string, ldap, path_trav, sqli, ssrf, ssti, xss, xxe};
|
||||
use super::{cmdi, deserialize, fmt_string, ldap, path_trav, sqli, ssrf, ssti, xpath, xss, xxe};
|
||||
use super::{CapCorpus, CuratedPayload, Oracle};
|
||||
use crate::dynamic::oracle::ProbePredicate;
|
||||
use crate::labels::Cap;
|
||||
|
|
@ -40,7 +40,6 @@ pub const CORPUS_UNSUPPORTED_LANG_NEUTRAL: u32 = Cap::ENV_VAR.bits()
|
|||
| Cap::CRYPTO.bits()
|
||||
| Cap::UNAUTHORIZED_ID.bits()
|
||||
| Cap::DATA_EXFIL.bits()
|
||||
| Cap::XPATH_INJECTION.bits()
|
||||
| Cap::HEADER_INJECTION.bits()
|
||||
| Cap::OPEN_REDIRECT.bits()
|
||||
| Cap::PROTOTYPE_POLLUTION.bits();
|
||||
|
|
@ -71,6 +70,10 @@ const ENTRIES: &[(Cap, Lang, &[CuratedPayload])] = &[
|
|||
(Cap::LDAP_INJECTION, Lang::Java, ldap::java::PAYLOADS),
|
||||
(Cap::LDAP_INJECTION, Lang::Python, ldap::python::PAYLOADS),
|
||||
(Cap::LDAP_INJECTION, Lang::Php, ldap::php::PAYLOADS),
|
||||
(Cap::XPATH_INJECTION, Lang::Java, xpath::java::PAYLOADS),
|
||||
(Cap::XPATH_INJECTION, Lang::Python, xpath::python::PAYLOADS),
|
||||
(Cap::XPATH_INJECTION, Lang::Php, xpath::php::PAYLOADS),
|
||||
(Cap::XPATH_INJECTION, Lang::JavaScript, xpath::js::PAYLOADS),
|
||||
];
|
||||
|
||||
/// Reserved for per-cap oracle defaults. Empty in Phase 02; populated by
|
||||
|
|
@ -281,6 +284,7 @@ mod tests {
|
|||
assert!(!payloads_for(Cap::SSTI).is_empty());
|
||||
assert!(!payloads_for(Cap::XXE).is_empty());
|
||||
assert!(!payloads_for(Cap::LDAP_INJECTION).is_empty());
|
||||
assert!(!payloads_for(Cap::XPATH_INJECTION).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -293,7 +297,6 @@ mod tests {
|
|||
Cap::CRYPTO,
|
||||
Cap::UNAUTHORIZED_ID,
|
||||
Cap::DATA_EXFIL,
|
||||
Cap::XPATH_INJECTION,
|
||||
Cap::HEADER_INJECTION,
|
||||
Cap::OPEN_REDIRECT,
|
||||
Cap::PROTOTYPE_POLLUTION,
|
||||
|
|
@ -328,6 +331,7 @@ mod tests {
|
|||
Cap::SSTI,
|
||||
Cap::XXE,
|
||||
Cap::LDAP_INJECTION,
|
||||
Cap::XPATH_INJECTION,
|
||||
] {
|
||||
let has_vuln = payloads_for(cap).iter().any(|p| !p.is_benign);
|
||||
assert!(has_vuln, "{cap:?} must have at least one vuln payload");
|
||||
|
|
@ -378,6 +382,7 @@ mod tests {
|
|||
Cap::SSTI,
|
||||
Cap::XXE,
|
||||
Cap::LDAP_INJECTION,
|
||||
Cap::XPATH_INJECTION,
|
||||
];
|
||||
for cap in caps {
|
||||
for p in payloads_for(cap) {
|
||||
|
|
@ -403,6 +408,7 @@ mod tests {
|
|||
Cap::SSTI,
|
||||
Cap::XXE,
|
||||
Cap::LDAP_INJECTION,
|
||||
Cap::XPATH_INJECTION,
|
||||
];
|
||||
for cap in caps {
|
||||
for p in payloads_for(cap) {
|
||||
|
|
@ -515,6 +521,7 @@ mod tests {
|
|||
Cap::SSTI,
|
||||
Cap::XXE,
|
||||
Cap::LDAP_INJECTION,
|
||||
Cap::XPATH_INJECTION,
|
||||
];
|
||||
for cap in caps {
|
||||
for p in payloads_for(cap).iter().filter(|p| p.is_benign) {
|
||||
|
|
@ -726,6 +733,48 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xpath_has_per_lang_slices_for_phase_07() {
|
||||
// Phase 07 (Track J.5) acceptance: XPATH_INJECTION registers
|
||||
// payloads in Java / Python / PHP / JavaScript and the
|
||||
// lang-aware lookup never returns empty for any of them.
|
||||
for lang in [Lang::Java, Lang::Python, Lang::Php, Lang::JavaScript] {
|
||||
assert!(
|
||||
!payloads_for_lang(Cap::XPATH_INJECTION, lang).is_empty(),
|
||||
"XPATH_INJECTION must have at least one payload for {lang:?}",
|
||||
);
|
||||
}
|
||||
// Rust / C / Cpp / Ruby / Go / TS not yet covered.
|
||||
for lang in [
|
||||
Lang::Rust,
|
||||
Lang::C,
|
||||
Lang::Cpp,
|
||||
Lang::Ruby,
|
||||
Lang::Go,
|
||||
Lang::TypeScript,
|
||||
] {
|
||||
assert!(
|
||||
payloads_for_lang(Cap::XPATH_INJECTION, lang).is_empty(),
|
||||
"XPATH_INJECTION has unexpected payloads for {lang:?}",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xpath_payloads_pair_benign_controls_per_lang() {
|
||||
for lang in [Lang::Java, Lang::Python, Lang::Php, Lang::JavaScript] {
|
||||
let slice = payloads_for_lang(Cap::XPATH_INJECTION, lang);
|
||||
let vuln = slice
|
||||
.iter()
|
||||
.find(|p| !p.is_benign)
|
||||
.expect("each lang must have an XPath vuln payload");
|
||||
let resolved =
|
||||
super::resolve_benign_control_lang(vuln, Cap::XPATH_INJECTION, lang)
|
||||
.expect("lang-aware benign control must resolve");
|
||||
assert!(resolved.is_benign);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_payloads_pair_benign_controls_per_lang() {
|
||||
// The lang-aware resolver must find the paired benign control
|
||||
|
|
|
|||
53
src/dynamic/corpus/xpath/java.rs
Normal file
53
src/dynamic/corpus/xpath/java.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//! Java `Cap::XPATH_INJECTION` payloads — `javax.xml.xpath.XPath.evaluate`
|
||||
//! expression injection.
|
||||
//!
|
||||
//! Vuln payload: an XPath fragment whose `' or '1'='1` tail breaks
|
||||
//! out of the host template's `[@name='…']` predicate and rewraps
|
||||
//! the selector as `//user[@name='' or '1'='1']`, matching every
|
||||
//! node the staged document carries. The harness's instrumented
|
||||
//! `XPath.evaluate` records
|
||||
//! `ProbeKind::Xpath { nodes_returned: 3 }`.
|
||||
//!
|
||||
//! Benign control: the same intended username quoted via the
|
||||
//! harness's XPath-escape helper, leaving the expression pinned to a
|
||||
//! single node — `nodes_returned: 1`, oracle clear.
|
||||
|
||||
use super::super::{CuratedPayload, Oracle, PayloadProvenance, PayloadRef};
|
||||
use crate::dynamic::oracle::ProbePredicate;
|
||||
|
||||
pub const PAYLOADS: &[CuratedPayload] = &[
|
||||
CuratedPayload {
|
||||
bytes: b"alice' or '1'='1",
|
||||
label: "xpath-java-expression-wildcard",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: false,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/java/Vuln.java"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
benign_control: Some(PayloadRef {
|
||||
label: "xpath-java-benign",
|
||||
}),
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
CuratedPayload {
|
||||
bytes: b"alice",
|
||||
label: "xpath-java-benign",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: true,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/java/Benign.java"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[],
|
||||
benign_control: None,
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
];
|
||||
53
src/dynamic/corpus/xpath/js.rs
Normal file
53
src/dynamic/corpus/xpath/js.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//! JavaScript `Cap::XPATH_INJECTION` payloads — `xpath` npm package's
|
||||
//! `select` expression injection.
|
||||
//!
|
||||
//! Vuln payload: an XPath fragment whose `' or '1'='1` tail breaks
|
||||
//! out of the host template's `[@name='…']` predicate; the
|
||||
//! synthesized expression becomes `//user[@name='' or '1'='1']` and
|
||||
//! matches every node in the staged document. The harness's
|
||||
//! instrumented `xpath.select` records
|
||||
//! `ProbeKind::Xpath { nodes_returned: 3 }`.
|
||||
//!
|
||||
//! Benign control: the same intended username quoted via the
|
||||
//! harness's XPath-escape helper, leaving the expression pinned to a
|
||||
//! single node — `nodes_returned: 1`, oracle clear.
|
||||
|
||||
use super::super::{CuratedPayload, Oracle, PayloadProvenance, PayloadRef};
|
||||
use crate::dynamic::oracle::ProbePredicate;
|
||||
|
||||
pub const PAYLOADS: &[CuratedPayload] = &[
|
||||
CuratedPayload {
|
||||
bytes: b"alice' or '1'='1",
|
||||
label: "xpath-js-expression-wildcard",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: false,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/js/vuln.js"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
benign_control: Some(PayloadRef {
|
||||
label: "xpath-js-benign",
|
||||
}),
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
CuratedPayload {
|
||||
bytes: b"alice",
|
||||
label: "xpath-js-benign",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: true,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/js/benign.js"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[],
|
||||
benign_control: None,
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
];
|
||||
29
src/dynamic/corpus/xpath/mod.rs
Normal file
29
src/dynamic/corpus/xpath/mod.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//! XPath expression injection (`Cap::XPATH_INJECTION`) per-language
|
||||
//! payload slices.
|
||||
//!
|
||||
//! Phase 07 (Track J.5) carves XPath injection across the four
|
||||
//! most-common XPath evaluator stacks: Java
|
||||
//! (`javax.xml.xpath.XPath.evaluate`), Python (`lxml.etree.xpath`),
|
||||
//! PHP (`DOMXPath::query`), and Node.js (`xpath` npm package's
|
||||
//! `select`). Every vuln payload appends the canonical
|
||||
//! `' or '1'='1` quote-escape break — once the host code substitutes
|
||||
//! the attacker bytes into its XPath template the synthesized
|
||||
//! expression selects every node the in-workdir
|
||||
//! [`crate::dynamic::stubs::xpath_document`] XML carries (three
|
||||
//! users). The paired benign control quotes the same bytes through
|
||||
//! the per-language escape helper, leaving the expression pinned to
|
||||
//! the originally-intended single node.
|
||||
//!
|
||||
//! The oracle's
|
||||
//! [`crate::dynamic::oracle::ProbePredicate::QueryResultCountGreaterThan`]
|
||||
//! checks the per-payload `ProbeKind::Xpath.nodes_returned` against
|
||||
//! `n = 1` — vuln passes (3 nodes), benign clears (1 node),
|
||||
//! fulfilling the §4.1 differential rule. The same predicate also
|
||||
//! satisfies LDAP probes (`ProbeKind::Ldap.entries_returned`); the
|
||||
//! Phase 06 → Phase 07 rename from `LdapResultCountGreaterThan` to
|
||||
//! `QueryResultCountGreaterThan` captures the shared shape.
|
||||
|
||||
pub mod java;
|
||||
pub mod js;
|
||||
pub mod php;
|
||||
pub mod python;
|
||||
53
src/dynamic/corpus/xpath/php.rs
Normal file
53
src/dynamic/corpus/xpath/php.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//! PHP `Cap::XPATH_INJECTION` payloads — `DOMXPath::query` expression
|
||||
//! injection.
|
||||
//!
|
||||
//! Vuln payload: an XPath fragment whose `' or '1'='1` tail breaks
|
||||
//! out of the host template's `[@name='…']` predicate; the
|
||||
//! synthesized expression becomes `//user[@name='' or '1'='1']` and
|
||||
//! matches every node in the staged document. The harness's
|
||||
//! instrumented `DOMXPath::query` records
|
||||
//! `ProbeKind::Xpath { nodes_returned: 3 }`.
|
||||
//!
|
||||
//! Benign control: the same intended username quoted via the
|
||||
//! harness's XPath-escape helper, leaving the expression pinned to a
|
||||
//! single node — `nodes_returned: 1`, oracle clear.
|
||||
|
||||
use super::super::{CuratedPayload, Oracle, PayloadProvenance, PayloadRef};
|
||||
use crate::dynamic::oracle::ProbePredicate;
|
||||
|
||||
pub const PAYLOADS: &[CuratedPayload] = &[
|
||||
CuratedPayload {
|
||||
bytes: b"alice' or '1'='1",
|
||||
label: "xpath-php-expression-wildcard",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: false,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/php/vuln.php"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
benign_control: Some(PayloadRef {
|
||||
label: "xpath-php-benign",
|
||||
}),
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
CuratedPayload {
|
||||
bytes: b"alice",
|
||||
label: "xpath-php-benign",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: true,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/php/benign.php"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[],
|
||||
benign_control: None,
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
];
|
||||
53
src/dynamic/corpus/xpath/python.rs
Normal file
53
src/dynamic/corpus/xpath/python.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
//! Python `Cap::XPATH_INJECTION` payloads — `lxml.etree.xpath`
|
||||
//! expression injection.
|
||||
//!
|
||||
//! Vuln payload: an XPath fragment whose `' or '1'='1` tail breaks
|
||||
//! out of the host template's `[@name='…']` predicate; the
|
||||
//! synthesized expression becomes `//user[@name='' or '1'='1']` and
|
||||
//! matches every node in the staged document. The harness's
|
||||
//! instrumented `xpath` evaluator records
|
||||
//! `ProbeKind::Xpath { nodes_returned: 3 }`.
|
||||
//!
|
||||
//! Benign control: the same intended username quoted via the
|
||||
//! harness's XPath-escape helper, leaving the expression pinned to a
|
||||
//! single node — `nodes_returned: 1`, oracle clear.
|
||||
|
||||
use super::super::{CuratedPayload, Oracle, PayloadProvenance, PayloadRef};
|
||||
use crate::dynamic::oracle::ProbePredicate;
|
||||
|
||||
pub const PAYLOADS: &[CuratedPayload] = &[
|
||||
CuratedPayload {
|
||||
bytes: b"alice' or '1'='1",
|
||||
label: "xpath-python-expression-wildcard",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: false,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/python/vuln.py"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
benign_control: Some(PayloadRef {
|
||||
label: "xpath-python-benign",
|
||||
}),
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
CuratedPayload {
|
||||
bytes: b"alice",
|
||||
label: "xpath-python-benign",
|
||||
oracle: Oracle::SinkProbe {
|
||||
predicates: &[ProbePredicate::QueryResultCountGreaterThan { n: 1 }],
|
||||
},
|
||||
is_benign: true,
|
||||
provenance: PayloadProvenance::Curated,
|
||||
since_corpus_version: 11,
|
||||
deprecated_at_corpus_version: None,
|
||||
fixture_paths: &["tests/dynamic_fixtures/xpath_injection/python/benign.py"],
|
||||
oob_nonce_slot: false,
|
||||
probe_predicates: &[],
|
||||
benign_control: None,
|
||||
no_benign_control_rationale: None,
|
||||
},
|
||||
];
|
||||
Loading…
Add table
Add a link
Reference in a new issue