#[non_exhaustive]pub struct SecurityConfig {
pub max_file_size: u64,
pub max_total_size: u64,
pub max_compression_ratio: f64,
pub max_file_count: usize,
pub max_path_depth: usize,
pub allowed: AllowedFeatures,
pub preserve_permissions: bool,
pub allowed_extensions: Vec<String>,
pub banned_path_components: Vec<String>,
pub allow_solid_archives: bool,
pub max_solid_block_memory: u64,
}Expand description
Security configuration with default-deny settings.
This configuration controls various security checks performed during archive extraction to prevent common vulnerabilities.
§Performance Note
This struct contains heap-allocated collections (Vec<String>). For
performance, pass by reference (&SecurityConfig) rather than cloning. If
shared ownership is needed across threads, consider wrapping in
Arc<SecurityConfig>.
§Examples
use exarch_core::SecurityConfig;
// Use secure defaults
let config = SecurityConfig::default();
// Customize via fluent builder
let custom = SecurityConfig::default()
.with_max_file_size(100 * 1024 * 1024)
.with_max_total_size(1024 * 1024 * 1024)
.with_allow_symlinks(true);Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.max_file_size: u64Maximum size for a single file in bytes.
max_total_size: u64Maximum total size for all extracted files in bytes.
max_compression_ratio: f64Maximum compression ratio allowed (uncompressed / compressed).
max_file_count: usizeMaximum number of files that can be extracted.
max_path_depth: usizeMaximum path depth allowed.
allowed: AllowedFeaturesFeature flags controlling what archive features are allowed.
Use this to enable symlinks, hardlinks, absolute paths, etc.
preserve_permissions: boolPreserve file permissions from archive.
allowed_extensions: Vec<String>List of allowed file extensions (empty = allow all).
Extensions are matched case-insensitively (e.g., "txt" matches both
file.txt and file.TXT). The leading dot must be omitted.
When this list is non-empty, files without a file extension are treated as not allowed and will be skipped during extraction.
banned_path_components: Vec<String>List of banned path components (e.g., “.git”, “.ssh”).
allow_solid_archives: boolAllow extraction from solid 7z archives.
Solid archives compress multiple files together as a single block. While this provides better compression ratios, it has security implications:
- Memory exhaustion: Extracting a single file requires decompressing the entire solid block into memory
- Denial of service: Malicious archives can create large solid blocks that exhaust available memory
Security Recommendation: Only enable for trusted archives.
Default: false (solid archives rejected)
max_solid_block_memory: u64Maximum memory for solid archive extraction (bytes).
7z Solid Archive Memory Model:
Solid compression in 7z stores multiple files in a single compressed block. Extracting ANY file requires decompressing the ENTIRE solid block into memory, which can cause memory exhaustion attacks.
Validation Strategy:
- Pre-validates total uncompressed size of all files in archive
- This is a conservative heuristic (assumes single solid block)
- Reason:
sevenz-rust2v0.20 doesn’t expose solid block boundaries
Security Guarantee:
- Total uncompressed data cannot exceed this limit
- Combined with
max_file_size, prevents unbounded memory growth - Enforced ONLY when
allow_solid_archivesistrue
Note: Only applies when allow_solid_archives is true.
Default: 512 MB (536,870,912 bytes)
Recommendation: Set to 1-2x available RAM for trusted archives only.
Implementations§
Source§impl SecurityConfig
impl SecurityConfig
Sourcepub fn permissive() -> Self
pub fn permissive() -> Self
Creates a permissive configuration for trusted archives.
This configuration allows symlinks, hardlinks, absolute paths, and solid archives. Use only when extracting archives from trusted sources.
Sourcepub fn validate(&self) -> Result<()>
pub fn validate(&self) -> Result<()>
Validates that the configuration values are logically consistent.
Returns an error if any field has a value that would make security enforcement impossible (zero limits or non-positive ratio).
§Errors
Returns ExtractionError::InvalidConfiguration if:
max_compression_ratiois not positivemax_file_sizeis zeromax_total_sizeis zeromax_path_depthis zeromax_file_countis zeromax_solid_block_memoryis zero
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default();
assert!(config.validate().is_ok());
let bad = SecurityConfig::default().with_max_file_size(0);
assert!(bad.validate().is_err());Sourcepub fn with_max_file_size(self, size: u64) -> Self
pub fn with_max_file_size(self, size: u64) -> Self
Sets the maximum size for a single extracted file in bytes.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_max_file_size(100 * 1024 * 1024);
assert_eq!(config.max_file_size, 100 * 1024 * 1024);Sourcepub fn with_max_total_size(self, size: u64) -> Self
pub fn with_max_total_size(self, size: u64) -> Self
Sets the maximum total size for all extracted files in bytes.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_max_total_size(1024 * 1024 * 1024);
assert_eq!(config.max_total_size, 1024 * 1024 * 1024);Sourcepub fn with_max_compression_ratio(self, ratio: f64) -> Self
pub fn with_max_compression_ratio(self, ratio: f64) -> Self
Sets the maximum allowed compression ratio (uncompressed / compressed).
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_max_compression_ratio(50.0);
assert_eq!(config.max_compression_ratio, 50.0);Sourcepub fn with_max_file_count(self, count: usize) -> Self
pub fn with_max_file_count(self, count: usize) -> Self
Sets the maximum number of files that can be extracted.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_max_file_count(500);
assert_eq!(config.max_file_count, 500);Sourcepub fn with_max_path_depth(self, depth: usize) -> Self
pub fn with_max_path_depth(self, depth: usize) -> Self
Sets the maximum path depth allowed.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_max_path_depth(16);
assert_eq!(config.max_path_depth, 16);Sourcepub fn with_allowed(self, allowed: AllowedFeatures) -> Self
pub fn with_allowed(self, allowed: AllowedFeatures) -> Self
Sets the feature flags controlling allowed archive features.
§Examples
use exarch_core::SecurityConfig;
use exarch_core::config::AllowedFeatures;
let features = AllowedFeatures::default();
let config = SecurityConfig::default().with_allowed(features);
assert!(!config.allowed.symlinks);Sourcepub fn with_allow_symlinks(self, allow: bool) -> Self
pub fn with_allow_symlinks(self, allow: bool) -> Self
Enables or disables symlinks in extracted archives.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_allow_symlinks(true);
assert!(config.allowed.symlinks);Sourcepub fn with_allow_hardlinks(self, allow: bool) -> Self
pub fn with_allow_hardlinks(self, allow: bool) -> Self
Enables or disables hardlinks in extracted archives.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_allow_hardlinks(true);
assert!(config.allowed.hardlinks);Sourcepub fn with_allow_absolute_paths(self, allow: bool) -> Self
pub fn with_allow_absolute_paths(self, allow: bool) -> Self
Enables or disables absolute paths in archive entries.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_allow_absolute_paths(true);
assert!(config.allowed.absolute_paths);Sourcepub fn with_allow_world_writable(self, allow: bool) -> Self
pub fn with_allow_world_writable(self, allow: bool) -> Self
Enables or disables world-writable files.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_allow_world_writable(true);
assert!(config.allowed.world_writable);Sourcepub fn with_preserve_permissions(self, preserve: bool) -> Self
pub fn with_preserve_permissions(self, preserve: bool) -> Self
Enables or disables preserving file permissions from the archive.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_preserve_permissions(true);
assert!(config.preserve_permissions);Sourcepub fn with_allowed_extensions(self, extensions: Vec<String>) -> Self
pub fn with_allowed_extensions(self, extensions: Vec<String>) -> Self
Sets the list of allowed file extensions.
An empty list allows all extensions.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default()
.with_allowed_extensions(vec!["txt".to_string(), "pdf".to_string()]);
assert!(config.is_extension_allowed("txt"));
assert!(!config.is_extension_allowed("exe"));Sourcepub fn with_banned_path_components(self, components: Vec<String>) -> Self
pub fn with_banned_path_components(self, components: Vec<String>) -> Self
Sets the list of banned path components.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_banned_path_components(vec![".git".to_string()]);
assert!(!config.is_path_component_allowed(".git"));
assert!(config.is_path_component_allowed(".ssh"));Sourcepub fn with_allow_solid_archives(self, allow: bool) -> Self
pub fn with_allow_solid_archives(self, allow: bool) -> Self
Enables or disables extraction from solid 7z archives.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_allow_solid_archives(true);
assert!(config.allow_solid_archives);Sourcepub fn with_max_solid_block_memory(self, size: u64) -> Self
pub fn with_max_solid_block_memory(self, size: u64) -> Self
Sets the maximum memory for solid archive extraction in bytes.
Only applies when allow_solid_archives is true.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default()
.with_allow_solid_archives(true)
.with_max_solid_block_memory(1024 * 1024 * 1024);
assert_eq!(config.max_solid_block_memory, 1024 * 1024 * 1024);Sourcepub fn is_path_component_allowed(&self, component: &str) -> bool
pub fn is_path_component_allowed(&self, component: &str) -> bool
Validates whether a path component is allowed.
Comparison is case-insensitive to prevent bypass on case-insensitive filesystems (Windows, macOS default).
Sourcepub fn is_extension_allowed(&self, extension: &str) -> bool
pub fn is_extension_allowed(&self, extension: &str) -> bool
Validates whether a file extension is allowed.
When allowed_extensions is empty, all extensions are permitted.
When it is non-empty, only listed extensions are permitted.
Sourcepub fn is_path_extension_allowed(&self, extension: Option<&str>) -> bool
pub fn is_path_extension_allowed(&self, extension: Option<&str>) -> bool
Returns true if a file with the given optional extension may be
extracted.
When allowed_extensions is non-empty and extension is None
(the file has no extension), the file is treated as not allowed.
§Examples
use exarch_core::SecurityConfig;
let config = SecurityConfig::default().with_allowed_extensions(vec!["txt".to_string()]);
assert!(config.is_path_extension_allowed(Some("txt")));
assert!(!config.is_path_extension_allowed(Some("exe")));
// Files without an extension are blocked when the allowlist is non-empty.
assert!(!config.is_path_extension_allowed(None));
// Empty allowlist permits everything, including extension-less files.
let permissive = SecurityConfig::default();
assert!(permissive.is_path_extension_allowed(None));Trait Implementations§
Source§impl Clone for SecurityConfig
impl Clone for SecurityConfig
Source§fn clone(&self) -> SecurityConfig
fn clone(&self) -> SecurityConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SecurityConfig
impl Debug for SecurityConfig
Source§impl Default for SecurityConfig
impl Default for SecurityConfig
Source§fn default() -> Self
fn default() -> Self
Creates a SecurityConfig with secure default settings.
Default values:
max_file_size: 50 MBmax_total_size: 500 MBmax_compression_ratio: 100.0max_file_count: 10,000max_path_depth: 32allowed: All features disabled (deny-by-default)preserve_permissions: falseallowed_extensions: empty (allow all)banned_path_components:[".git", ".ssh", ".gnupg", ".aws", ".kube", ".docker", ".env"]allow_solid_archives: false (solid archives rejected)max_solid_block_memory: 512 MB