use std::path::Path;
use tokio::fs;
use super::types::{SecurityLevel, ValidationResult};
use super::PackageValidator;
impl PackageValidator {
pub(super) async fn assess_security(&self, package_path: &Path, result: &mut ValidationResult) {
let mut security_issues = 0;
match fs::metadata(package_path).await {
Ok(metadata) => {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mode = metadata.permissions().mode();
if mode & 0o002 != 0 {
result
.warnings
.push("Package file is world-writable".to_string());
security_issues += 1;
}
if mode & 0o111 == 0 {
result
.warnings
.push("Package file is not executable".to_string());
}
}
}
Err(e) => {
result
.warnings
.push(format!("Cannot check file permissions: {}", e));
}
}
match fs::read(package_path).await {
Ok(data) => {
let suspicious_patterns: [&[u8]; 6] =
[b"/bin/sh", b"system(", b"exec", b"curl", b"wget", b"nc "];
for pattern in &suspicious_patterns {
if data.windows(pattern.len()).any(|window| window == *pattern) {
result.warnings.push(format!(
"Package contains potentially suspicious pattern: {}",
String::from_utf8_lossy(pattern)
));
security_issues += 1;
}
}
}
Err(e) => {
result
.warnings
.push(format!("Cannot read package for security analysis: {}", e));
}
}
result.security_level = if security_issues == 0 {
SecurityLevel::Safe
} else if security_issues <= 2 {
SecurityLevel::Warning
} else {
SecurityLevel::Dangerous
};
}
}