refactor(bare): enhance security and performance optimizations
- Remove unnecessary sorting in advertise_refs for deterministic output - Add path traversal detection and validation in bare_dir construction - Implement symlink resolution checks to prevent security vulnerabilities - Refactor cache system with CRC validation and improved metrics - Integrate repo-specific cache invalidation using indexed keys - Add comprehensive unit tests for commit operations and diff functionality - Move configuration constants to centralized config module - Optimize string operations in disk cache random value generation - Enhance license detection algorithm with cleaner matching logic - Streamline argument processing in various git operations - Update dependencies including crc32fast and flate2 for performance - Add signal handling capability to tokio runtime configuration
This commit is contained in:
+32
-12
@@ -25,7 +25,6 @@ const FORBIDDEN_PATTERNS: &[&str] = &[
|
||||
"init 6",
|
||||
"poweroff",
|
||||
"halt",
|
||||
// Additional patterns to catch encoding/obfuscation attempts
|
||||
"eval ", // eval can execute arbitrary strings
|
||||
"exec ", // exec can replace process
|
||||
"$(", // command substitution
|
||||
@@ -55,8 +54,21 @@ const DANGEROUS_PREFIXES: &[&str] = &[
|
||||
"rm -rf *", // rm -rf with wildcard
|
||||
];
|
||||
|
||||
/// Maximum hook script size (64KB).
|
||||
const MAX_HOOK_SIZE: usize = 65536;
|
||||
/// Pairs of commands that indicate data exfiltration or code execution.
|
||||
const DANGEROUS_COMMAND_PAIRS: &[(&str, &str)] = &[
|
||||
("curl", "bash"),
|
||||
("curl", "sh"),
|
||||
("wget", "bash"),
|
||||
("wget", "sh"),
|
||||
("nc", "-e"),
|
||||
("ncat", "-e"),
|
||||
("python", "-c"),
|
||||
("perl", "-e"),
|
||||
("ruby", "-e"),
|
||||
("node", "-e"),
|
||||
];
|
||||
|
||||
use crate::config::MAX_HOOK_SCRIPT_SIZE;
|
||||
|
||||
/// Validate a custom hook script content for safety.
|
||||
pub fn validate_hook_content(content: &str) -> GitResult<()> {
|
||||
@@ -65,10 +77,10 @@ pub fn validate_hook_content(content: &str) -> GitResult<()> {
|
||||
"hook content cannot be empty".into(),
|
||||
));
|
||||
}
|
||||
if content.len() > MAX_HOOK_SIZE {
|
||||
if content.len() > MAX_HOOK_SCRIPT_SIZE {
|
||||
return Err(GitError::InvalidArgument(format!(
|
||||
"hook content too large (max {} bytes): {} bytes",
|
||||
MAX_HOOK_SIZE,
|
||||
MAX_HOOK_SCRIPT_SIZE,
|
||||
content.len()
|
||||
)));
|
||||
}
|
||||
@@ -78,7 +90,6 @@ pub fn validate_hook_content(content: &str) -> GitResult<()> {
|
||||
));
|
||||
}
|
||||
|
||||
// Check for forbidden patterns (case-insensitive where appropriate)
|
||||
let content_lower = content.to_lowercase();
|
||||
for pattern in FORBIDDEN_PATTERNS {
|
||||
if content_lower.contains(&pattern.to_lowercase()) {
|
||||
@@ -88,7 +99,6 @@ pub fn validate_hook_content(content: &str) -> GitResult<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for dangerous prefixes (exact case)
|
||||
for prefix in DANGEROUS_PREFIXES {
|
||||
if content.contains(prefix) {
|
||||
return Err(GitError::InvalidArgument(format!(
|
||||
@@ -97,15 +107,28 @@ pub fn validate_hook_content(content: &str) -> GitResult<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for obfuscation techniques
|
||||
check_obfuscation_attempts(content)?;
|
||||
|
||||
check_dangerous_pairs(content)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check for dangerous command pairs that indicate data exfiltration or code execution.
|
||||
fn check_dangerous_pairs(content: &str) -> GitResult<()> {
|
||||
let content_lower = content.to_lowercase();
|
||||
for &(cmd1, cmd2) in DANGEROUS_COMMAND_PAIRS {
|
||||
if content_lower.contains(cmd1) && content_lower.contains(cmd2) {
|
||||
return Err(GitError::InvalidArgument(format!(
|
||||
"hook contains dangerous command combination: '{cmd1}' + '{cmd2}' (possible data exfiltration)"
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check for common obfuscation attempts.
|
||||
fn check_obfuscation_attempts(content: &str) -> GitResult<()> {
|
||||
// Check for excessive use of special characters that might indicate obfuscation
|
||||
let special_char_count = content
|
||||
.chars()
|
||||
.filter(|c| {
|
||||
@@ -117,14 +140,12 @@ fn check_obfuscation_attempts(content: &str) -> GitResult<()> {
|
||||
.count();
|
||||
let total_chars = content.chars().count();
|
||||
|
||||
// If more than 30% of content is special characters, it's suspicious
|
||||
if total_chars > 0 && (special_char_count * 100 / total_chars) > 30 {
|
||||
return Err(GitError::InvalidArgument(
|
||||
"hook content appears obfuscated (too many special characters)".into(),
|
||||
));
|
||||
}
|
||||
|
||||
// Check for hex encoding attempts (e.g., \x41\x42)
|
||||
if content.contains("\\x") {
|
||||
let hex_count = content.matches("\\x").count();
|
||||
if hex_count > 5 {
|
||||
@@ -134,7 +155,6 @@ fn check_obfuscation_attempts(content: &str) -> GitResult<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for unicode escape sequences
|
||||
if content.contains("\\u") {
|
||||
let unicode_count = content.matches("\\u").count();
|
||||
if unicode_count > 5 {
|
||||
|
||||
Reference in New Issue
Block a user