use anyhow::Result;
use kindly_guard_server::{
config::Config,
neutralizer::ThreatNeutralizer,
scanner::{SecurityScanner, Severity},
ScannerConfig,
};
use std::sync::Arc;
#[tokio::test]
async fn test_problematic_neutralization() -> Result<()> {
let _ = tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.try_init();
let scanner_config = ScannerConfig {
unicode_detection: true,
injection_detection: true,
path_traversal_detection: true,
custom_patterns: None,
max_scan_depth: 10,
enable_event_buffer: false,
xss_detection: Some(true),
enhanced_mode: Some(false),
crypto_detection: true,
max_content_size: 5 * 1024 * 1024,
};
let scanner = Arc::new(SecurityScanner::new(scanner_config)?);
let config = Config::default();
let neutralizer =
kindly_guard_server::neutralizer::create_neutralizer(&config.neutralization, None);
let input = "'\u{200b} OR\u{200b} '1'='1'\u{200b} --a";
println!("Testing input: {:?}", input);
let visible_input: String = input
.chars()
.map(|c| match c {
'\u{200b}' => "[ZWS]".to_string(),
_ => c.to_string(),
})
.collect();
println!("Visible representation: {}", visible_input);
let threats = scanner.scan_text(input)?;
println!("\nDetected {} threats:", threats.len());
for (i, threat) in threats.iter().enumerate() {
println!(
" Threat {}: {:?} (severity: {:?})",
i + 1,
threat.threat_type,
threat.severity
);
println!(" Description: {}", threat.description);
}
if !threats.is_empty() {
println!("\nNeutralizing threats...");
let batch_result = neutralizer.batch_neutralize(&threats, input).await?;
println!("\nNeutralization results:");
println!(
" Individual results: {}",
batch_result.individual_results.len()
);
for (i, result) in batch_result.individual_results.iter().enumerate() {
println!(
" Result {}: action={:?}, confidence={}",
i + 1,
result.action_taken,
result.confidence_score
);
}
println!("\nFinal content: {:?}", batch_result.final_content);
let visible_final: String = batch_result
.final_content
.chars()
.map(|c| match c {
'\u{200b}' => "[ZWS]".to_string(),
_ => c.to_string(),
})
.collect();
println!("Visible final content: {}", visible_final);
let final_threats = scanner.scan_text(&batch_result.final_content)?;
println!("\nThreats in neutralized content: {}", final_threats.len());
for (i, threat) in final_threats.iter().enumerate() {
println!(
" Remaining threat {}: {:?} (severity: {:?})",
i + 1,
threat.threat_type,
threat.severity
);
println!(" Description: {}", threat.description);
}
let high_severity_count = final_threats
.iter()
.filter(|t| !matches!(t.severity, Severity::Low))
.count();
if high_severity_count > 0 {
println!(
"\nERROR: {} high/medium/critical severity threats remain!",
high_severity_count
);
panic!("High severity threats remain after neutralization");
} else {
println!("\nSUCCESS: All high severity threats neutralized!");
}
}
Ok(())
}