-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Implement file transfer filtering infrastructure #164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Implement file transfer filtering infrastructure #164
Conversation
Add a complete filtering infrastructure for SFTP and SCP file transfer operations: - TransferFilter trait with check() and check_with_dest() methods - Operation enum: Upload, Download, Delete, Rename, CreateDir, ListDir, Stat, SetStat, Symlink, ReadLink - FilterResult: Allow, Deny, Log actions - FilterPolicy engine with first-match-wins rule evaluation - Matcher trait for extensible path matching Built-in matchers: - GlobMatcher: wildcard patterns (*.key, *.pem) - RegexMatcher: full regex support - PrefixMatcher: directory tree matching (/etc/*) - ExactMatcher: specific file matching - ComponentMatcher: match path components (.git, .ssh) - ExtensionMatcher: file extension matching - CombinedMatcher: OR-combine multiple matchers - NotMatcher: invert matcher results Configuration: - Extended FilterConfig with default_action, rule names, operations, and users - FilterRule supports per-user and per-operation restrictions - YAML configuration via existing config loader Closes #138
Security & Performance ReviewAnalysis Summary
Prioritized Fix RoadmapCRITICAL
HIGH
MEDIUM
LOW
Technical DetailsPath Traversal (CRITICAL) // Current implementation in path.rs:70
fn matches(&self, path: &Path) -> bool {
path.starts_with(&self.prefix) // Raw path comparison
}
// Attack vector:
// Filter blocks /etc/*
// Attacker requests /var/../etc/passwd -> bypasses filterReDoS (HIGH) // pattern.rs:162-164 - No size/complexity limits
let regex = Regex::new(pattern)
.with_context(|| format!("Invalid regex pattern: {}", pattern))?;Glob Matching Inconsistency (HIGH) // pattern.rs:91-107 - Dual matching strategy can cause bypasses
fn matches(&self, path: &Path) -> bool {
if self.pattern.matches_path(path) { return true; }
// Also matches just filename - potential bypass
if let Some(filename) = path.file_name() {
if let Some(filename_str) = filename.to_str() {
if self.pattern.matches(filename_str) { return true; }
}
}
false
}Progress Log
Manual Review Required
|
Priority: MEDIUM Issue: Three clippy warnings causing build failures with -D warnings - Derive Default instead of manual impl for FilterResult - Remove needless borrow in rule_from_config() - Rename CombinedMatcher::add() to with_matcher() to avoid confusion with std::ops::Add Review-Iteration: 1
Priority: HIGH Issue: RegexMatcher accepted arbitrary regex patterns without complexity limits, allowing potential CPU exhaustion via crafted patterns - Use RegexBuilder with size_limit and dfa_size_limit (1MB default) - Add with_size_limit() constructor for custom limits - Add test for size limit functionality Review-Iteration: 1
Priority: HIGH Issue: GlobMatcher tried both full path and filename matching, which could lead to unintended matches in security-sensitive filtering - Add GlobMatchMode enum (PathOrFilename, FullPathOnly, FilenameOnly) - Add with_mode() constructor for explicit control - Document matching behavior and security implications - Add tests for each match mode Review-Iteration: 1
Priority: CRITICAL Issue: Path matchers operated on raw paths without normalization, allowing bypass via path traversal sequences like ../ - Add normalize_path() function for logical path normalization - Add comprehensive security documentation - Document that callers should normalize paths before matching - Add tests demonstrating the security issue and fix Review-Iteration: 1
Review Progress UpdateCompleted Fixes (Iteration 1)CRITICAL
HIGH
MEDIUM
Remaining Items (for next iteration or manual review)MEDIUM
LOW
Test ResultsSummary of Changes
Commits
Next StepsThe CRITICAL and HIGH priority issues have been addressed. The remaining MEDIUM and LOW items are improvements that can be addressed in follow-up PRs or discussed further. |
Review CompleteFinal StatusAll CRITICAL and HIGH priority security issues have been addressed in this iteration. Summary
Security Fixes Applied
Test ResultsRemaining Items (for follow-up)
RecommendationThe PR is ready for merge after addressing the security issues. The remaining MEDIUM/LOW items can be addressed in follow-up PRs as they are improvements rather than vulnerabilities. Total iterations: 1/3 |
- Add tests for FilterPolicy.from_config() with glob patterns and prefixes - Add tests for FilterPolicy accessor methods (rule_count, default_action) - Add tests for FilterRule.matches() with all conditions - Add tests for SharedFilterPolicy (check_with_dest, From impl) - Add tests for Operation.all() and additional parse/display tests - Add tests for matcher accessor methods (prefix, path, component, extension) - Add tests for GlobMatchMode enum and CombinedMatcher len/is_empty - Fix normalize_path tests placement (move inside test module) - Update ARCHITECTURE.md with File Transfer Filter module documentation
PR Finalization ReportProject Structure Discovered
ChecklistTests
New tests added:
Documentation
Code Quality
Changes Made
|
Summary
Implementation Details
Core Types
Operationenum: Upload, Download, Delete, Rename, CreateDir, ListDir, Stat, SetStat, Symlink, ReadLinkFilterResultenum: Allow, Deny, LogTransferFiltertrait for implementing custom filter logicMatchertrait for extensible path pattern matchingBuilt-in Matchers
*.key,*.pem(?i)\.exe$/etc//etc/shadow.git,.sshexe,keyConfiguration
Filter rules support:
Test Plan
Closes #138