use tracing::warn;
use waf_core::{Config, Decision, Phase, RequestContext, ScoreItem, Severity, WafModule};
pub const RULE_NULL_BYTE: &str = "evasion-null-byte";
pub const RULE_DOUBLE_ENCODING: &str = "evasion-double-encoding";
#[derive(Default)]
pub struct EvasionModule;
impl EvasionModule {
pub fn new() -> Self {
Self
}
}
impl WafModule for EvasionModule {
fn id(&self) -> &str {
"evasion"
}
fn phase(&self) -> Phase {
Phase::Body
}
fn structural(&self) -> bool {
true
}
fn init(&mut self, _cfg: &Config) {}
fn inspect(&self, ctx: &RequestContext) -> Decision {
let mut items: Vec<ScoreItem> = Vec::new();
if ctx.normalized.null_byte_detected {
warn!(
request_id = %ctx.request_id,
rule_id = RULE_NULL_BYTE,
severity = ?Severity::Critical,
"evasion detection"
);
items.push(ScoreItem {
rule_id: RULE_NULL_BYTE.to_string(),
severity: Severity::Critical,
});
}
if ctx.normalized.double_encoding_detected {
warn!(
request_id = %ctx.request_id,
rule_id = RULE_DOUBLE_ENCODING,
severity = ?Severity::Warning,
"evasion detection"
);
items.push(ScoreItem {
rule_id: RULE_DOUBLE_ENCODING.to_string(),
severity: Severity::Warning,
});
}
if items.is_empty() {
Decision::Allow
} else {
Decision::Scores(items)
}
}
}