From 3c6f4a97dc042f1ddd266503b38738a6e493d0ec Mon Sep 17 00:00:00 2001 From: "ilblackdragon@gmail.com" Date: Mon, 9 Mar 2026 23:09:25 -0700 Subject: [PATCH] fix: improve fuzz targets to exercise real IronClaw code paths - fuzz_config_env: exercise SafetyLayer end-to-end (sanitize, validate, policy check) instead of generic TOML/JSON parsing - fuzz_tool_params: add validate_tool_schema coverage alongside validate_tool_params - Add "fuzz" to workspace exclude in root Cargo.toml - Update README descriptions to match actual target behavior [skip-regression-check] Co-Authored-By: Claude Opus 4.6 --- Cargo.toml | 1 + fuzz/README.md | 4 ++-- fuzz/fuzz_targets/fuzz_config_env.rs | 25 +++++++++++++++++++++---- fuzz/fuzz_targets/fuzz_tool_params.rs | 5 +++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1e1d909a..b35b1c46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ exclude = [ "tools-src/google-slides", "tools-src/slack", "tools-src/telegram", + "fuzz", ] [package] diff --git a/fuzz/README.md b/fuzz/README.md index 13a31565..c4c27c69 100644 --- a/fuzz/README.md +++ b/fuzz/README.md @@ -9,8 +9,8 @@ Fuzz testing for security-critical input parsing paths using [cargo-fuzz](https: | `fuzz_safety_sanitizer` | Prompt injection pattern detection (Aho-Corasick + regex) | | `fuzz_safety_validator` | Input validation (length, encoding, forbidden patterns) | | `fuzz_leak_detector` | Secret leak detection (API keys, tokens, credentials) | -| `fuzz_tool_params` | Tool parameter JSON validation pipeline | -| `fuzz_config_env` | Configuration parsing (TOML, JSON) | +| `fuzz_tool_params` | Tool parameter and schema JSON validation | +| `fuzz_config_env` | SafetyLayer end-to-end (sanitize, validate, policy check) | ## Setup diff --git a/fuzz/fuzz_targets/fuzz_config_env.rs b/fuzz/fuzz_targets/fuzz_config_env.rs index 52c8943c..617bda05 100644 --- a/fuzz/fuzz_targets/fuzz_config_env.rs +++ b/fuzz/fuzz_targets/fuzz_config_env.rs @@ -1,12 +1,29 @@ #![no_main] use libfuzzer_sys::fuzz_target; +use ironclaw::config::SafetyConfig; + fuzz_target!(|data: &[u8]| { if let Ok(s) = std::str::from_utf8(data) { - // Exercise TOML config parsing with arbitrary input - let _ = toml::from_str::(s); + // SafetyConfig fields are parsed from env vars. We cannot safely set + // env vars in a multi-threaded fuzzer, but we can exercise the types + // that config parsing produces by constructing SafetyConfig directly + // and feeding the fuzzed string through the safety layer it creates. - // Exercise JSON config parsing - let _ = serde_json::from_str::(s); + // Parse the fuzzed input as a potential max_output_length value. + let max_len: usize = s.parse().unwrap_or(100_000); + + let config = SafetyConfig { + max_output_length: max_len, + injection_check_enabled: true, + }; + + // Build a SafetyLayer from the config and exercise it. + let layer = ironclaw::safety::SafetyLayer::new(&config); + + // Use the fuzzed string as tool output content. + let _ = layer.sanitize_tool_output("fuzz_tool", s); + let _ = layer.validate_input(s); + let _ = layer.check_policy(s); } }); diff --git a/fuzz/fuzz_targets/fuzz_tool_params.rs b/fuzz/fuzz_targets/fuzz_tool_params.rs index 201477b6..52e39867 100644 --- a/fuzz/fuzz_targets/fuzz_tool_params.rs +++ b/fuzz/fuzz_targets/fuzz_tool_params.rs @@ -1,17 +1,22 @@ #![no_main] use libfuzzer_sys::fuzz_target; use ironclaw::safety::Validator; +use ironclaw::tools::validate_tool_schema; fuzz_target!(|data: &[u8]| { if let Ok(s) = std::str::from_utf8(data) { // Try parsing as JSON and validating as tool parameters if let Ok(value) = serde_json::from_str::(s) { + // Exercise Validator::validate_tool_params with arbitrary JSON let validator = Validator::new(); let result = validator.validate_tool_params(&value); // Invariant: result should always be well-formed if !result.is_valid { assert!(!result.errors.is_empty()); } + + // Exercise validate_tool_schema with arbitrary JSON as a schema + let _ = validate_tool_schema(&value, "fuzz"); } } });