mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-09 19:45:13 +02:00
[pitboss/grind] deferred session-0009 (20260520T233019Z-6958)
This commit is contained in:
parent
a6f34554db
commit
38cc0ce05f
60 changed files with 509 additions and 541 deletions
|
|
@ -256,7 +256,7 @@ pub struct FixtureSpec<'a> {
|
|||
///
|
||||
/// Captures the fields a regression test must pin: status + typed reasons
|
||||
/// + whether a payload triggered. Excludes machine-dependent fields
|
||||
/// (`finding_id`, `detail`, `attempts`, `toolchain_match`).
|
||||
/// (`finding_id`, `detail`, `attempts`, `toolchain_match`).
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct GoldenVerdict {
|
||||
pub status: VerifyStatus,
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ use std::collections::BTreeSet;
|
|||
const RUN_COUNT: usize = 10;
|
||||
|
||||
fn deny_diag(stable_hash: u64) -> Diag {
|
||||
let mut ev = Evidence::default();
|
||||
// Triggers the credentials deny rule via the AWS-key regex from
|
||||
// `crate::utils::redact::contains_secret`. The deny rule fires
|
||||
// deterministically because the rule lookup table is `const`.
|
||||
ev.notes = vec!["secret=AKIAFAKEDETERM00000000".to_owned()];
|
||||
let ev = Evidence {
|
||||
notes: vec!["secret=AKIAFAKEDETERM00000000".to_owned()],
|
||||
..Evidence::default()
|
||||
};
|
||||
Diag {
|
||||
path: "src/handler.py".to_owned(),
|
||||
line: 42,
|
||||
|
|
@ -84,9 +86,11 @@ fn ten_runs_produce_byte_identical_telemetry_minus_timestamps() {
|
|||
|
||||
let diag = deny_diag(0x0123_4567_89ab_cdef);
|
||||
|
||||
let mut opts = VerifyOptions::default();
|
||||
opts.telemetry_policy = SamplingPolicy::keep_all();
|
||||
opts.trace_verbose = false;
|
||||
let opts = VerifyOptions {
|
||||
telemetry_policy: SamplingPolicy::keep_all(),
|
||||
trace_verbose: false,
|
||||
..VerifyOptions::default()
|
||||
};
|
||||
|
||||
let mut verdict_jsons: BTreeSet<String> = BTreeSet::new();
|
||||
for _ in 0..RUN_COUNT {
|
||||
|
|
|
|||
|
|
@ -127,11 +127,10 @@ mod parity_tests {
|
|||
// BackendUnavailable into Unsupported OR Inconclusive depending on
|
||||
// where the error surfaces, so the skip predicate looks at the
|
||||
// reason text, not the verdict status.
|
||||
if let Some(ref r) = docker_result.reason {
|
||||
if format!("{r:?}").contains("BackendUnavailable") {
|
||||
if let Some(ref r) = docker_result.reason
|
||||
&& format!("{r:?}").contains("BackendUnavailable") {
|
||||
return; // Docker absent — skip comparison.
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
process_result.status, docker_result.status,
|
||||
|
|
|
|||
|
|
@ -189,8 +189,10 @@ mod verify_e2e {
|
|||
|
||||
let diag = taint_diag_with_cap(Cap::CRYPTO);
|
||||
let trace = Arc::new(VerifyTrace::new());
|
||||
let mut opts = VerifyOptions::default();
|
||||
opts.trace_sink = Some(Arc::clone(&trace));
|
||||
let opts = VerifyOptions {
|
||||
trace_sink: Some(Arc::clone(&trace)),
|
||||
..VerifyOptions::default()
|
||||
};
|
||||
|
||||
let _result = verify_finding(&diag, &opts);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ fn scan_with_hashes(dir: &Path) -> Vec<nyx_scanner::commands::scan::Diag> {
|
|||
|
||||
/// Attach a simulated dynamic verdict to every finding in the list.
|
||||
fn set_verdict(
|
||||
diags: &mut Vec<nyx_scanner::commands::scan::Diag>,
|
||||
diags: &mut [nyx_scanner::commands::scan::Diag],
|
||||
status: VerifyStatus,
|
||||
) {
|
||||
for d in diags.iter_mut() {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(deprecated)]
|
||||
//! Marker uniqueness test (§4.1, §17.4).
|
||||
//!
|
||||
//! Asserts that no `NYX_PWN_*` marker from one cap's corpus is a substring
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::field_reassign_with_default)]
|
||||
//! Phase 30 (Track C — security): coverage for
|
||||
//! [`crate::dynamic::policy::evaluate`] deny rules.
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -142,12 +142,13 @@ fn flask_eval_verdict() -> VerifyResult {
|
|||
}
|
||||
|
||||
fn flask_eval_sandbox_options() -> SandboxOptions {
|
||||
let mut opts = SandboxOptions::default();
|
||||
opts.backend = SandboxBackend::Docker;
|
||||
opts.env_passthrough = vec!["NYX_PAYLOAD".into()];
|
||||
opts.timeout = Duration::from_secs(30);
|
||||
opts.memory_mib = 256;
|
||||
opts
|
||||
SandboxOptions {
|
||||
backend: SandboxBackend::Docker,
|
||||
env_passthrough: vec!["NYX_PAYLOAD".into()],
|
||||
timeout: Duration::from_secs(30),
|
||||
memory_mib: 256,
|
||||
..SandboxOptions::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn workspace_root() -> PathBuf {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::field_reassign_with_default)]
|
||||
//! Phase 04 acceptance: callgraph-aware
|
||||
//! [`SpecDerivationStrategy::FromCallgraphEntry`].
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::field_reassign_with_default)]
|
||||
//! Phase 01, Track A.1: integration coverage for
|
||||
//! `HarnessSpec::from_finding_opts` strategy fall-through.
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -27,34 +27,36 @@ use nyx_scanner::patterns::{FindingCategory, Severity};
|
|||
/// and a synthetic per-name summary, so the framework adapter registry
|
||||
/// resolves a binding when the fixture's source matches an adapter.
|
||||
fn make_diag(path: &str, handler: &str, line: usize, cap: Cap, rule_id: &str) -> Diag {
|
||||
let mut ev = Evidence::default();
|
||||
ev.flow_steps = vec![
|
||||
FlowStep {
|
||||
step: 0,
|
||||
kind: FlowStepKind::Source,
|
||||
file: path.into(),
|
||||
line: line as u32,
|
||||
col: 0,
|
||||
snippet: None,
|
||||
variable: None,
|
||||
callee: None,
|
||||
function: Some(handler.into()),
|
||||
is_cross_file: false,
|
||||
},
|
||||
FlowStep {
|
||||
step: 1,
|
||||
kind: FlowStepKind::Sink,
|
||||
file: path.into(),
|
||||
line: line as u32,
|
||||
col: 0,
|
||||
snippet: None,
|
||||
variable: None,
|
||||
callee: None,
|
||||
function: Some(handler.into()),
|
||||
is_cross_file: false,
|
||||
},
|
||||
];
|
||||
ev.sink_caps = cap.bits();
|
||||
let ev = Evidence {
|
||||
flow_steps: vec![
|
||||
FlowStep {
|
||||
step: 0,
|
||||
kind: FlowStepKind::Source,
|
||||
file: path.into(),
|
||||
line: line as u32,
|
||||
col: 0,
|
||||
snippet: None,
|
||||
variable: None,
|
||||
callee: None,
|
||||
function: Some(handler.into()),
|
||||
is_cross_file: false,
|
||||
},
|
||||
FlowStep {
|
||||
step: 1,
|
||||
kind: FlowStepKind::Sink,
|
||||
file: path.into(),
|
||||
line: line as u32,
|
||||
col: 0,
|
||||
snippet: None,
|
||||
variable: None,
|
||||
callee: None,
|
||||
function: Some(handler.into()),
|
||||
is_cross_file: false,
|
||||
},
|
||||
],
|
||||
sink_caps: cap.bits(),
|
||||
..Evidence::default()
|
||||
};
|
||||
Diag {
|
||||
path: path.into(),
|
||||
line,
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ fn read_fixture(stub_dir: &str, name: &str) -> String {
|
|||
/// begin with `//`; the payload is the surviving line.
|
||||
fn extract_payload(s: &str) -> String {
|
||||
s.lines()
|
||||
.filter(|l| !l.trim().is_empty() && !l.trim_start().starts_with("//"))
|
||||
.last()
|
||||
.rfind(|l| !l.trim().is_empty() && !l.trim_start().starts_with("//"))
|
||||
.unwrap_or("")
|
||||
.trim()
|
||||
.to_owned()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue