mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-15 20:05:13 +02:00
[pitboss/grind] deferred session-0011 (20260522T043516Z-29b8)
This commit is contained in:
parent
189bcb79d4
commit
205fb142c8
12 changed files with 195 additions and 75 deletions
|
|
@ -22,7 +22,7 @@ use nyx_scanner::dynamic::corpus::{
|
|||
use nyx_scanner::dynamic::framework::registry::adapters_for;
|
||||
use nyx_scanner::dynamic::lang;
|
||||
use nyx_scanner::dynamic::oracle::{ProbePredicate, oracle_fired};
|
||||
use nyx_scanner::dynamic::probe::{ProbeKind, ProbeWitness, SinkProbe};
|
||||
use nyx_scanner::dynamic::probe::{HeaderEmitProtocol, ProbeKind, ProbeWitness, SinkProbe};
|
||||
use nyx_scanner::dynamic::sandbox::SandboxOutcome;
|
||||
use nyx_scanner::dynamic::spec::{EntryKind, HarnessSpec, PayloadSlot};
|
||||
use nyx_scanner::labels::Cap;
|
||||
|
|
@ -158,15 +158,53 @@ fn probe_kind_header_emit_serdes() {
|
|||
let original = ProbeKind::HeaderEmit {
|
||||
name: "Set-Cookie".into(),
|
||||
value: "nyx-session\r\nSet-Cookie: nyx-injected=pwn".into(),
|
||||
protocol: HeaderEmitProtocol::InProcess,
|
||||
};
|
||||
let json = serde_json::to_string(&original).unwrap();
|
||||
assert!(json.contains("HeaderEmit"));
|
||||
assert!(json.contains("name"));
|
||||
assert!(json.contains("value"));
|
||||
assert!(json.contains("\"protocol\":\"in-process\""));
|
||||
let parsed: ProbeKind = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(parsed, original);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_kind_header_emit_serdes_wire_variant() {
|
||||
let original = ProbeKind::HeaderEmit {
|
||||
name: "Set-Cookie".into(),
|
||||
value: "nyx-session\r\nSet-Cookie: nyx-injected=pwn".into(),
|
||||
protocol: HeaderEmitProtocol::Wire,
|
||||
};
|
||||
let json = serde_json::to_string(&original).unwrap();
|
||||
assert!(json.contains("\"protocol\":\"wire\""));
|
||||
let parsed: ProbeKind = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(parsed, original);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_kind_header_emit_deserialises_legacy_records_as_in_process() {
|
||||
// Probe records emitted before the protocol field existed must
|
||||
// continue to deserialise via the `#[serde(default)]` hatch so the
|
||||
// future oracle tightening landing does not need to migrate the
|
||||
// on-disk channel format.
|
||||
let legacy_json =
|
||||
r#"{"kind":"HeaderEmit","name":"Set-Cookie","value":"nyx-session\r\nSet-Cookie: pwn"}"#;
|
||||
let parsed: ProbeKind = serde_json::from_str(legacy_json).unwrap();
|
||||
match parsed {
|
||||
ProbeKind::HeaderEmit {
|
||||
name,
|
||||
value,
|
||||
protocol,
|
||||
} => {
|
||||
assert_eq!(name, "Set-Cookie");
|
||||
assert_eq!(value, "nyx-session\r\nSet-Cookie: pwn");
|
||||
assert_eq!(protocol, HeaderEmitProtocol::InProcess);
|
||||
}
|
||||
other => panic!("expected HeaderEmit, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn header_injected_predicate_fires_on_crlf_value() {
|
||||
let oracle = Oracle::SinkProbe {
|
||||
|
|
@ -182,6 +220,7 @@ fn header_injected_predicate_fires_on_crlf_value() {
|
|||
kind: ProbeKind::HeaderEmit {
|
||||
name: "Set-Cookie".into(),
|
||||
value: "nyx-session\r\nSet-Cookie: nyx-injected=pwn".into(),
|
||||
protocol: HeaderEmitProtocol::InProcess,
|
||||
},
|
||||
witness: ProbeWitness::empty(),
|
||||
}];
|
||||
|
|
@ -213,6 +252,7 @@ fn header_injected_predicate_clear_when_value_is_url_encoded() {
|
|||
kind: ProbeKind::HeaderEmit {
|
||||
name: "Set-Cookie".into(),
|
||||
value: "nyx-session%0D%0ASet-Cookie%3A%20nyx-injected%3Dpwn".into(),
|
||||
protocol: HeaderEmitProtocol::InProcess,
|
||||
},
|
||||
witness: ProbeWitness::empty(),
|
||||
}];
|
||||
|
|
@ -246,6 +286,7 @@ fn header_injected_predicate_clear_on_unrelated_header() {
|
|||
kind: ProbeKind::HeaderEmit {
|
||||
name: "X-Trace-Id".into(),
|
||||
value: "trace\r\nX-Injected: 1".into(),
|
||||
protocol: HeaderEmitProtocol::InProcess,
|
||||
},
|
||||
witness: ProbeWitness::empty(),
|
||||
}];
|
||||
|
|
|
|||
|
|
@ -254,8 +254,23 @@ fn lang_emitter_dispatches_to_prototype_pollution_harness() {
|
|||
"{lang:?} harness must install the canary trap on Object.prototype",
|
||||
);
|
||||
assert!(
|
||||
harness.source.contains("nyxDeepMerge"),
|
||||
"{lang:?} harness must inline the deep-merge sink",
|
||||
harness.source.contains("require('lodash').merge"),
|
||||
"{lang:?} harness must route through the real `lodash.merge` (Phase 10 follow-up swap)",
|
||||
);
|
||||
assert!(
|
||||
!harness.source.contains("function nyxDeepMerge"),
|
||||
"{lang:?} harness must no longer declare the hand-rolled `nyxDeepMerge` shim",
|
||||
);
|
||||
assert!(
|
||||
!harness.source.contains("nyxDeepMerge(target,"),
|
||||
"{lang:?} harness must no longer call the hand-rolled `nyxDeepMerge` shim",
|
||||
);
|
||||
assert!(
|
||||
harness
|
||||
.extra_files
|
||||
.iter()
|
||||
.any(|(p, c)| p == "package.json" && c.contains("\"lodash\":\"4.17.4\"")),
|
||||
"{lang:?} harness must publish a `package.json` pinning lodash 4.17.4 (last version before `_.merge` was hardened against `__proto__`); empirical bisect shows 4.17.5+ already filters the key so newer pins flip the vuln fixture to NotConfirmed",
|
||||
);
|
||||
assert!(
|
||||
harness.source.contains("__NYX_SINK_HIT__"),
|
||||
|
|
|
|||
|
|
@ -549,6 +549,17 @@ mod e2e_phase_07 {
|
|||
.as_ref()
|
||||
.expect("Confirmed run must carry a DifferentialOutcome");
|
||||
assert_eq!(diff.verdict, DifferentialVerdict::Confirmed);
|
||||
let tier_a_marker = b"__NYX_XPATH_TIER_A__";
|
||||
let saw_tier_a = outcome.attempts.iter().any(|a| {
|
||||
a.outcome
|
||||
.stdout
|
||||
.windows(tier_a_marker.len())
|
||||
.any(|w| w == tier_a_marker)
|
||||
});
|
||||
assert!(
|
||||
saw_tier_a,
|
||||
"Python XPath vuln must reach the tier-(a) real-lxml path (stdout marker `__NYX_XPATH_TIER_A__`); the inline `_nyx_xpath_select` fallback was removed and the harness now SKIPs via NYX_IMPORT_ERROR + exit 77 when lxml is unavailable",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue