pub struct SecurityScanner {
pub patterns: ThreatPatterns,
/* private fields */
}Expand description
Main security scanner combining all threat detection
The SecurityScanner is the central component for detecting security threats in text and JSON inputs.
It combines multiple specialized scanners (Unicode, Injection, XSS, Crypto) and supports plugin-based extensions.
§Architecture
- Unicode Scanner: Detects invisible characters, BiDi spoofing, homograph attacks
- Injection Scanner: Detects SQL, command, prompt, and other injection attempts
- XSS Scanner: Detects cross-site scripting patterns
- Crypto Scanner: Detects weak cryptographic patterns and insecure implementations
- Plugin System: Allows custom threat detection via external plugins
§Security Considerations
- All scanners run with configurable depth limits to prevent DoS attacks
- Pattern matching uses size-limited regex to prevent ReDoS attacks
- Results are type-safe using enums, never raw strings for security decisions
- Enhanced mode provides additional correlation and pattern analysis
§Performance
- Scanners use zero-copy operations where possible
- Text is scanned in a single pass per scanner
- JSON scanning uses recursive descent with depth limiting
- Enhanced mode may use SIMD optimizations when available
Fields§
§patterns: ThreatPatternsImplementations§
Source§impl SecurityScanner
impl SecurityScanner
Sourcepub fn set_plugin_manager(
&mut self,
plugin_manager: Arc<dyn PluginManagerTrait>,
)
pub fn set_plugin_manager( &mut self, plugin_manager: Arc<dyn PluginManagerTrait>, )
Set the plugin manager for this scanner
Enables plugin-based threat detection by attaching a plugin manager to the scanner. Plugins can detect custom threats specific to your application or domain.
§Arguments
plugin_manager- The plugin manager that will coordinate plugin scanning
§Plugin Security
- Plugins run in isolated contexts with limited permissions
- Plugin errors are logged but don’t fail the main scan
- Each plugin has configurable timeouts to prevent DoS
§Example
let mut scanner = SecurityScanner::new(Default::default())?;
scanner.set_plugin_manager(plugin_manager);Sourcepub fn new(config: ScannerConfig) -> Result<Self, ScanError>
pub fn new(config: ScannerConfig) -> Result<Self, ScanError>
Create a new security scanner with the given configuration
Initializes all sub-scanners and loads threat patterns based on the provided configuration.
§Arguments
config- Scanner configuration controlling detection features and limits
§Configuration Options
unicode_detection: Enable/disable Unicode threat detectioninjection_detection: Enable/disable injection attack detectionxss_detection: Enable/disable XSS detectionmax_scan_depth: Maximum recursion depth for JSON scanning (default: 20)custom_patterns: Optional path to custom threat pattern fileenhanced_mode: Enable enhanced detection with advanced correlation
§Returns
Ok(SecurityScanner)- Configured scanner ready for threat detectionErr(ScanError)- If pattern loading or scanner initialization fails
§Errors
ScanError::PatternError- If custom patterns file is invalidScanError::InvalidInput- If scanner initialization fails
§Security Best Practices
- Always validate the custom patterns file path if provided
- Set appropriate
max_scan_depthto prevent stack exhaustion - Enable all detection types unless you have specific requirements
§Example
use kindly_guard_server::config::ScannerConfig;
use kindly_guard_server::scanner::SecurityScanner;
// Basic configuration with all protections enabled
let config = ScannerConfig {
unicode_detection: true,
injection_detection: true,
xss_detection: Some(true),
max_scan_depth: 20,
custom_patterns: None,
enhanced_mode: Some(false),
enable_event_buffer: false,
crypto_detection: true,
max_content_size: 5_242_880, // 5MB
};
let scanner = SecurityScanner::new(config)?;§Performance Notes
- Scanner initialization is relatively expensive due to pattern compilation
- Reuse scanner instances across multiple scans for better performance
- Enhanced mode may increase memory usage but improves detection accuracy
Sourcepub fn with_processor(
config: ScannerConfig,
event_processor: Option<Arc<dyn SecurityEventProcessor>>,
) -> Result<Self, ScanError>
pub fn with_processor( config: ScannerConfig, event_processor: Option<Arc<dyn SecurityEventProcessor>>, ) -> Result<Self, ScanError>
Create a new security scanner with an optional event processor
This method allows creation of a scanner with enhanced capabilities through an event processor for advanced threat correlation and pattern analysis.
§Arguments
config- Scanner configurationevent_processor- Optional processor for enhanced threat analysis
§Enhanced Mode Features
When an event processor is provided and enable_event_buffer is true:
- Real-time threat correlation across multiple scans
- Pattern analysis for identifying attack campaigns
- Performance optimizations through event batching
- Advanced metrics and analytics
§Implementation Note
This follows the trait-based architecture pattern where enhanced implementations are hidden behind trait abstractions, allowing for both standard and optimized scanning modes without exposing implementation details.
Sourcepub fn scan_text(&self, text: &str) -> ScanResult
pub fn scan_text(&self, text: &str) -> ScanResult
Scan text for threats
Sourcepub fn scan_json(&self, value: &Value) -> ScanResult
pub fn scan_json(&self, value: &Value) -> ScanResult
Scan JSON value for security threats
Recursively scans a JSON structure for threats in all string values and object keys. This method is essential for securing API endpoints that accept JSON payloads.
§Arguments
value- The JSON value to scan (can be any valid JSON type)
§Returns
Ok(Vec<Threat>)- List of detected threats with JSON path locationsErr(ScanError)- If scanning fails or depth limit is exceeded
§Security Considerations
- Depth Limiting: Prevents stack exhaustion from deeply nested JSON
- Key Scanning: Object keys are scanned as they can contain payloads
- Path Tracking: Each threat includes the JSON path for precise location
- Type Safety: Only string values are scanned (numbers/bools are safe)
§JSON Path Format
Threats are reported with JSON paths for easy identification:
- Root:
$ - Object field:
$.fieldor$.parent.child - Array element:
$[0]or$.array[2] - Nested:
$.users[0].name
§Error Handling
ScanError::MaxDepthExceeded- If nesting exceedsmax_scan_depthScanError::InvalidInput- If JSON serialization fails- Plugin errors are logged but don’t fail the scan
§Example
use kindly_guard_server::scanner::{SecurityScanner, Location};
use serde_json::json;
// Scan a JSON API request
let request = json!({
"user": {
"name": "admin' OR '1'='1",
"bio": "Hello\u{202E}World", // BiDi override
"tags": ["safe", "<script>alert(1)</script>"]
}
});
let threats = scanner.scan_json(&request)?;
for threat in threats {
if let Location::Json { path } = &threat.location {
eprintln!("Threat at {}: {}", path, threat.description);
// Outputs:
// Threat at $.user.name: SQL Injection
// Threat at $.user.bio: BiDi Text Spoofing
// Threat at $.user.tags[1]: Cross-Site Scripting
}
}§Performance and Security Trade-offs
- Depth vs Security: Lower
max_scan_depthprevents DoS but may miss threats - Memory Usage: Large JSON structures consume memory proportional to depth
- Scan Time: O(n) where n is total number of string values in JSON
- Recommendation: Set depth limit based on expected legitimate nesting
§Best Practices
- Validate JSON schema before scanning for structural attacks
- Consider rate limiting based on JSON size/complexity
- Log scan results for security monitoring and pattern analysis
- Implement allowlists for known-safe patterns to reduce false positives
Sourcepub fn stats(&self) -> ScannerStats
pub fn stats(&self) -> ScannerStats
Get scanner statistics for monitoring and analysis
Returns current statistics from all enabled scanners including:
- Total number of scans performed
- Number of threats detected by type
- Performance metrics when enhanced mode is enabled
§Thread Safety
Statistics are collected using atomic operations and are safe to read while scanning is in progress on other threads.
§Example
let stats = scanner.stats();
println!("Total scans: {}", stats.total_scans);
println!("Unicode threats: {}", stats.unicode_threats_detected);
println!("Injection threats: {}", stats.injection_threats_detected);Trait Implementations§
Source§impl SecurityScannerTrait for SecurityScanner
impl SecurityScannerTrait for SecurityScanner
Source§fn get_stats(&self) -> ScannerStats
fn get_stats(&self) -> ScannerStats
Source§fn reset_stats(&self)
fn reset_stats(&self)
Auto Trait Implementations§
impl !Freeze for SecurityScanner
impl !RefUnwindSafe for SecurityScanner
impl Send for SecurityScanner
impl Sync for SecurityScanner
impl Unpin for SecurityScanner
impl !UnwindSafe for SecurityScanner
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more