mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-15 20:05:13 +02:00
[pitboss/grind] deferred session-0003 (20260522T163126Z-7d60)
This commit is contained in:
parent
3486056f5e
commit
0e4e393000
6 changed files with 612 additions and 4 deletions
33
tests/dynamic_fixtures/json_parse_depth/java/Vuln.java
Normal file
33
tests/dynamic_fixtures/json_parse_depth/java/Vuln.java
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Java JSON_PARSE depth-bomb vuln fixture.
|
||||
//
|
||||
// Models a config-driven JSON ingest endpoint that picks the parser
|
||||
// input based on the request payload tag - `*_DEEP` routes through a
|
||||
// deeply-nested array literal (256 levels) that drives the parser past
|
||||
// the 64-level depth budget; `*_SHALLOW` routes through a flat `[]`
|
||||
// parse that leaves the predicate clear. This shape is needed by the
|
||||
// differential runner: the vuln-payload attempt and the benign-control
|
||||
// attempt both load the same fixture, and only the payload-routed
|
||||
// deep branch trips the `JsonParseExcessiveDepth` predicate.
|
||||
//
|
||||
// Java has no stdlib JSON parser. The harness ships a hand-rolled
|
||||
// iterative `NyxJsonProbe.parse(String)` helper alongside `NyxHarness`
|
||||
// so the fixture does not need to link Jackson / Gson at build time.
|
||||
// The helper returns a `java.util.List` / `java.util.Map` tree the
|
||||
// harness then walks via `NyxJsonProbe.countDepth(Object)` to produce
|
||||
// the `ProbeKind::JsonParse { depth }` record.
|
||||
public class Vuln {
|
||||
public static Object run(String value) {
|
||||
String text = value == null ? "" : value;
|
||||
if (text.contains("DEEP")) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 256; i++) {
|
||||
sb.append('[');
|
||||
}
|
||||
for (int i = 0; i < 256; i++) {
|
||||
sb.append(']');
|
||||
}
|
||||
return NyxJsonProbe.parse(sb.toString());
|
||||
}
|
||||
return NyxJsonProbe.parse("[]");
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ const LANGS: &[Lang] = &[
|
|||
Lang::Php,
|
||||
Lang::Go,
|
||||
Lang::Rust,
|
||||
Lang::Java,
|
||||
];
|
||||
|
||||
/// Subset of [`LANGS`] whose JSON parser has a prototype-pollution
|
||||
|
|
@ -181,7 +182,8 @@ mod e2e_json_parse_depth {
|
|||
Lang::Php => "php",
|
||||
Lang::Go => "go",
|
||||
Lang::Rust => "rust",
|
||||
_ => unreachable!("JSON_PARSE depth e2e covers JS / Python / Ruby / PHP / Go / Rust only"),
|
||||
Lang::Java => "java",
|
||||
_ => unreachable!("JSON_PARSE depth e2e covers JS / Python / Ruby / PHP / Go / Rust / Java only"),
|
||||
})
|
||||
.join(fixture);
|
||||
let tmp = TempDir::new().expect("create tempdir");
|
||||
|
|
@ -227,7 +229,8 @@ mod e2e_json_parse_depth {
|
|||
Lang::Php => "php",
|
||||
Lang::Go => "go",
|
||||
Lang::Rust => "cargo",
|
||||
_ => unreachable!("JSON_PARSE depth e2e covers JS / Python / Ruby / PHP / Go / Rust only"),
|
||||
Lang::Java => "javac",
|
||||
_ => unreachable!("JSON_PARSE depth e2e covers JS / Python / Ruby / PHP / Go / Rust / Java only"),
|
||||
};
|
||||
if !command_available(required) {
|
||||
eprintln!("SKIP {lang:?} {fixture}: missing toolchain {required}");
|
||||
|
|
@ -310,11 +313,19 @@ mod e2e_json_parse_depth {
|
|||
};
|
||||
assert_confirmed(Lang::Rust, &outcome);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn java_vuln_confirms_via_run_spec() {
|
||||
let Some(outcome) = run(Lang::Java, "Vuln.java", "run") else {
|
||||
return;
|
||||
};
|
||||
assert_confirmed(Lang::Java, &outcome);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_parse_unsupported_for_other_langs() {
|
||||
for lang in [Lang::C, Lang::Cpp, Lang::Java, Lang::TypeScript] {
|
||||
for lang in [Lang::C, Lang::Cpp, Lang::TypeScript] {
|
||||
assert!(
|
||||
payloads_for_lang(Cap::JSON_PARSE, lang).is_empty(),
|
||||
"JSON_PARSE has unexpected payloads for {lang:?}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue