wafrift-wafmodel 0.3.1

Active-learning WAF decompiler: reconstruct a WAF's decision boundary as an executable symbolic automaton, mine bypasses offline, and prove hole-closure.
Documentation
//! # wafrift-wafmodel — the WAF decompiler
//!
//! Stop searching a black box. **Reconstruct the WAF's decision
//! boundary as an executable symbolic automaton**, then turn evasion
//! from search into deduction:
//!
//! - **P1 — Decompile.** Active-learn the WAF (the [`learn`] module)
//!   over a [`WafOracle`] into an [`Sfa`], spending the minimum
//!   membership-query budget. Emit it as a provenance-stamped artifact.
//! - **P1 — Mine.** Intersect the learned pass-language with an attack
//!   grammar *offline* to harvest minimal-edit bypasses with no further
//!   live queries.
//! - **P2 — Solve.** Compose the learned WAF view with the pipeline's
//!   normalization transducers and solve for inputs that survive every
//!   stage (the double-decode trick, rediscovered — not hard-coded).
//! - **P3 — Dominate.** The same model drives constrained adversarial
//!   evasion of ML-WAFs *and* provable hole-closure for defenders.
//!
//! Everything here is zero-config and pure-Rust: no GPU, no external
//! Coraza, no network required for the core. Acceleration (vyre/GPU,
//! live HTTP oracles) is strictly additive.
//!
//! The crate is built bottom-up; each module is landed complete (no
//! stubs) before the next depends on it. This file only declares
//! modules that are fully implemented.

#![forbid(unsafe_code)]

/// The shipped Tier-B OWASP-CRS-derived ruleset (XSS 941 + SQLi 942),
/// embedded so `wafrift audit`/`harden` work zero-config with no files
/// to fetch. Parse with [`SimRegexWaf::from_toml`].
#[must_use]
pub fn default_crs_ruleset() -> &'static str {
    include_str!("../rules/crs/core.toml")
}

pub mod artifact;
pub mod booster;
pub mod canon;
pub mod ensemble_dilution;
pub mod equiv_bridge;
pub mod equiv_query;
pub mod error;
pub mod filter_profile;
pub mod harden;
pub mod learn;
pub mod mine;
pub mod mlwaf;
pub mod normalize;
pub mod oracle;
pub mod origin_probe;
pub mod outcome;
pub mod sfa;
pub mod solve;
pub mod transduce;

pub use artifact::{LearnedModel, Provenance};
pub use booster::WafBoosterScorer;
pub use canon::{CanonView, Channel, Segment, canonicalize};
pub use ensemble_dilution::RuleGroup;
pub use equiv_bridge::{norm_mismatch_members, sink_for_tag, solution_member};
pub use equiv_query::{ChainedEq, PacBound, SampledEq, UcbBanditEq, WMethodEq};
pub use error::{Result, WafModelError};
pub use filter_profile::{
    DecodeGap, FilterProfile, TokenFinding, TokenProbe, Verdict, battery_from_toml, characterize,
    default_battery as default_filter_battery, probe_decode_gaps,
};
pub use harden::{ClosureReport, synthesize_closure};
pub use learn::{
    Alphabet, BoundedExhaustiveEq, EquivalenceOracle, LearnReport, kv_learn, l_star,
    l_star_budgeted, passive_learn,
};
pub use mine::{attack_grammar, mine_bypasses, minimal_bypass, waf_diff};
pub use mlwaf::{MlEvasion, MlWaf, evade_ml};
pub use normalize::{Transform, apply_chain};
pub use oracle::{ChannelSet, FnOracle, Rule, SimRegexWaf, WafOracle};
pub use origin_probe::{
    FnReflector, OriginScan, ReflectionOracle, detect_origin_normalization, scan_origin,
};
pub use outcome::Outcome;
pub use sfa::{BytePred, Sfa, StateId};
pub use solve::{Solution, solve_bypass};
pub use transduce::{Pipeline, Stage, json_unescape, url_decode_once};