[pitboss/grind] deferred session-0006 (20260522T163126Z-7d60)

This commit is contained in:
pitboss 2026-05-22 13:54:16 -05:00
parent 94a3d12a4e
commit 77d671060a
3 changed files with 515 additions and 4 deletions

View file

@ -146,7 +146,8 @@ mod e2e_data_exfil {
.join("tests/dynamic_fixtures/data_exfil")
.join(match lang {
Lang::Python => "python",
_ => unreachable!("DATA_EXFIL e2e currently covers Python only"),
Lang::Ruby => "ruby",
_ => unreachable!("DATA_EXFIL e2e currently covers Python + Ruby"),
})
.join(fixture);
let tmp = TempDir::new().expect("create tempdir");
@ -187,7 +188,8 @@ mod e2e_data_exfil {
fn run(lang: Lang, fixture: &str, entry_name: &str) -> Option<RunOutcome> {
let required = match lang {
Lang::Python => "python3",
_ => unreachable!("DATA_EXFIL e2e currently covers Python only"),
Lang::Ruby => "ruby",
_ => unreachable!("DATA_EXFIL e2e currently covers Python + Ruby"),
};
if !command_available(required) {
eprintln!("SKIP {lang:?} {fixture}: missing toolchain {required}");
@ -253,4 +255,37 @@ mod e2e_data_exfil {
"Python DATA_EXFIL benign control must not confirm via run_spec; got {outcome:?}",
);
}
/// Ruby pair, same shape as Python: the vuln fixture always calls
/// `Net::HTTP.get(uri)` and the harness's open-class shim records
/// the URI host; the benign fixture early-returns when the host
/// argument is not in `ALLOWLIST` so no `Net::HTTP.get` call is
/// made for the attacker payload. Skips when `ruby` is not on
/// PATH.
#[test]
fn ruby_vuln_confirms_via_run_spec() {
let Some(outcome) = run(Lang::Ruby, "vuln.rb", "run") else {
return;
};
assert!(
outcome.triggered_by.is_some(),
"Ruby DATA_EXFIL vuln must confirm via run_spec; got {outcome:?}",
);
let diff = outcome
.differential
.as_ref()
.expect("confirmed run must carry a DifferentialOutcome");
assert_eq!(diff.verdict, DifferentialVerdict::Confirmed);
}
#[test]
fn ruby_benign_does_not_confirm_via_run_spec() {
let Some(outcome) = run(Lang::Ruby, "benign.rb", "run") else {
return;
};
assert!(
outcome.triggered_by.is_none(),
"Ruby DATA_EXFIL benign control must not confirm via run_spec; got {outcome:?}",
);
}
}

View file

@ -137,7 +137,8 @@ mod e2e_unauthorized_id {
.join("tests/dynamic_fixtures/unauthorized_id")
.join(match lang {
Lang::Python => "python",
_ => unreachable!("UNAUTHORIZED_ID e2e currently covers Python only"),
Lang::Ruby => "ruby",
_ => unreachable!("UNAUTHORIZED_ID e2e currently covers Python + Ruby"),
})
.join(fixture);
let tmp = TempDir::new().expect("create tempdir");
@ -178,7 +179,8 @@ mod e2e_unauthorized_id {
fn run(lang: Lang, fixture: &str, entry_name: &str) -> Option<RunOutcome> {
let required = match lang {
Lang::Python => "python3",
_ => unreachable!("UNAUTHORIZED_ID e2e currently covers Python only"),
Lang::Ruby => "ruby",
_ => unreachable!("UNAUTHORIZED_ID e2e currently covers Python + Ruby"),
};
if !command_available(required) {
eprintln!("SKIP {lang:?} {fixture}: missing toolchain {required}");
@ -246,4 +248,34 @@ mod e2e_unauthorized_id {
"Python UNAUTHORIZED_ID benign control must not confirm via run_spec; got {outcome:?}",
);
}
/// Ruby pair, same shape as Python: the vuln fixture returns the
/// record for any owner_id, the benign fixture returns nil when
/// owner_id != caller_id. Skips when `ruby` is not on PATH.
#[test]
fn ruby_vuln_confirms_via_run_spec() {
let Some(outcome) = run(Lang::Ruby, "vuln.rb", "run") else {
return;
};
assert!(
outcome.triggered_by.is_some(),
"Ruby UNAUTHORIZED_ID vuln must confirm via run_spec; got {outcome:?}",
);
let diff = outcome
.differential
.as_ref()
.expect("confirmed run must carry a DifferentialOutcome");
assert_eq!(diff.verdict, DifferentialVerdict::Confirmed);
}
#[test]
fn ruby_benign_does_not_confirm_via_run_spec() {
let Some(outcome) = run(Lang::Ruby, "benign.rb", "run") else {
return;
};
assert!(
outcome.triggered_by.is_none(),
"Ruby UNAUTHORIZED_ID benign control must not confirm via run_spec; got {outcome:?}",
);
}
}