[pitboss/grind] deferred session-0005 (20260520T233019Z-6958)

This commit is contained in:
pitboss 2026-05-20 22:31:58 -05:00
parent 787da2975f
commit c885a8d424
4 changed files with 150 additions and 21 deletions

View file

@ -120,13 +120,16 @@ mod parity_tests {
/// Assert two verdicts agree on status (and on reason for non-Confirmed).
fn assert_parity(fixture: &str, process_result: &nyx_scanner::evidence::VerifyResult,
docker_result: &nyx_scanner::evidence::VerifyResult) {
// If docker backend is unavailable, docker result will be Unsupported.
// That's acceptable — we can't compare when docker is missing.
if docker_result.status == VerifyStatus::Unsupported {
if let Some(ref r) = docker_result.reason {
if format!("{r:?}").contains("BackendUnavailable") {
return; // Docker absent — skip comparison.
}
// Docker reachability fluctuates per host: `docker info` may exit 0
// (daemon listening) while the sandbox's container-start path still
// fails (image not pulled, socket gated by Docker Desktop's
// privileged-mode toggle, etc.). The downstream verifier folds
// 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") {
return; // Docker absent — skip comparison.
}
}

View file

@ -322,10 +322,11 @@ fn slug(lang: Lang) -> &'static str {
// `ProbePredicate::TemplateEvalEqual { expected: 49 }` → differential
// pair against the `7*7` benign control.
//
// Java is skipped: the Thymeleaf fixture imports `org.thymeleaf.*`
// which is not on the JDK stdlib, so `javac *.java` over the workdir
// fails before the synthetic harness can run. Phase 04 deferred
// item 5 (real-engine Thymeleaf harness) is the structural fix.
// Java/Thymeleaf rides the Maven plumbing added in `prepare_java`:
// the harness ships a `pom.xml` via `extra_files`, prepare_java runs
// `mvn dependency:copy-dependencies -DoutputDirectory=lib` to stage
// `org.thymeleaf.*` jars, and javac compiles with `-cp .:lib/*`.
// The e2e cell SKIPs when `mvn` or `javac` is absent on the host.
mod e2e_phase_04 {
use crate::common::fixture_harness::FIXTURE_LOCK;
@ -355,7 +356,8 @@ mod e2e_phase_04 {
Lang::Ruby => "ruby",
Lang::Php => "php",
Lang::JavaScript => "node",
_ => unreachable!("e2e_phase_04 covers Python/Ruby/PHP/JS only"),
Lang::Java => "javac",
_ => unreachable!("e2e_phase_04 covers Python/Ruby/PHP/JS/Java only"),
}
}
@ -365,6 +367,7 @@ mod e2e_phase_04 {
Lang::Ruby => "ruby_erb",
Lang::Php => "php_twig",
Lang::JavaScript => "js_handlebars",
Lang::Java => "java_thymeleaf",
_ => unreachable!(),
}
}
@ -417,6 +420,12 @@ mod e2e_phase_04 {
eprintln!("SKIP {lang:?} {fixture}: missing toolchain {bin}");
return None;
}
// Java/Thymeleaf also needs Maven on PATH to resolve the
// Thymeleaf jars before javac runs.
if matches!(lang, Lang::Java) && !command_available("mvn") {
eprintln!("SKIP {lang:?} {fixture}: missing mvn for dependency resolution");
return None;
}
let _guard = FIXTURE_LOCK.lock().unwrap_or_else(|e| e.into_inner());
let (spec, _tmp) = build_spec(lang, fixture, entry_name);
let opts = SandboxOptions {
@ -490,4 +499,18 @@ mod e2e_phase_04 {
.expect("Confirmed run must carry a DifferentialOutcome");
assert_eq!(diff.verdict, DifferentialVerdict::Confirmed);
}
#[test]
fn java_thymeleaf_vuln_confirms_via_run_spec() {
let Some(outcome) = run(Lang::Java, "vuln.java", "run") else { return };
assert!(
outcome.triggered_by.is_some(),
"Java Thymeleaf SSTI 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);
}
}