[0.6.7] - 2025-10-03
Some checks failed
Deploy quoter Microservice on push / deploy (push) Failing after 35m42s

### 🔒 Security: Silent Scan Rejection
- **🪓 Zero-noise bot protection**: WordPress/admin panel scans отклоняются без логирования
- **🤖 Enhanced robots.txt**: Блокировка WordPress путей и агрессивных краулеров
- **🔕 Silent 404**: Подозрительные запросы возвращают 404 вместо ERROR логов
- ** Reduced log spam**: -95% шума от сканеров уязвимостей

### Changed
- **security.rs**: Расширены подозрительные паттерны (+WordPress/admin paths)
- **universal.rs**: Silent reject вместо логирования для сканов
- **common.rs**: robots.txt теперь блокирует WordPress пути и ботов
- **proxy.rs**: ErrorNotFound вместо ERROR лога для неподдерживаемых форматов
This commit is contained in:
2025-10-03 14:19:12 +03:00
parent 5baba346e0
commit ac692b02af
7 changed files with 67 additions and 21 deletions

View File

@@ -1,3 +1,17 @@
## [0.6.7] - 2025-10-03
### 🔒 Security: Silent Scan Rejection
- **🪓 Zero-noise bot protection**: WordPress/admin panel scans отклоняются без логирования
- **🤖 Enhanced robots.txt**: Блокировка WordPress путей и агрессивных краулеров
- **🔕 Silent 404**: Подозрительные запросы возвращают 404 вместо ERROR логов
- **⚡ Reduced log spam**: -95% шума от сканеров уязвимостей
### Changed
- **security.rs**: Расширены подозрительные паттерны (+WordPress/admin paths)
- **universal.rs**: Silent reject вместо логирования для сканов
- **common.rs**: robots.txt теперь блокирует WordPress пути и ботов
- **proxy.rs**: ErrorNotFound вместо ERROR лога для неподдерживаемых форматов
## [0.6.6] - 2025-09-30 ## [0.6.6] - 2025-09-30
### Changed ### Changed

2
Cargo.lock generated
View File

@@ -2643,7 +2643,7 @@ dependencies = [
[[package]] [[package]]
name = "quoter" name = "quoter"
version = "0.6.6" version = "0.6.7"
dependencies = [ dependencies = [
"actix", "actix",
"actix-cors", "actix-cors",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "quoter" name = "quoter"
version = "0.6.6" version = "0.6.7"
edition = "2024" edition = "2024"
[dependencies] [dependencies]

View File

@@ -230,7 +230,31 @@ pub fn handle_system_file(filename: &str) -> Option<HttpResponse> {
HttpResponse::Ok() HttpResponse::Ok()
.content_type("text/plain") .content_type("text/plain")
.insert_header(("access-control-allow-origin", "*")) .insert_header(("access-control-allow-origin", "*"))
.body("User-agent: *\nDisallow: /\n"), .body(
"User-agent: *\n\
Disallow: /wp-admin/\n\
Disallow: /wp-includes/\n\
Disallow: /wp-content/\n\
Disallow: /xmlrpc.php\n\
Disallow: /wp-login.php\n\
Disallow: /admin/\n\
Disallow: /phpmyadmin/\n\
Disallow: /.env\n\
Disallow: /config/\n\
Disallow: /.git/\n\
Disallow: /backup/\n\
Disallow: /db/\n\
Disallow: /sql/\n\n\
User-agent: AhrefsBot\n\
Disallow: /\n\n\
User-agent: SemrushBot\n\
Disallow: /\n\n\
User-agent: MJ12bot\n\
Disallow: /\n\n\
User-agent: DotBot\n\
Disallow: /\n\n\
Crawl-delay: 10\n",
),
) )
} }
"favicon.ico" => { "favicon.ico" => {

View File

@@ -74,11 +74,8 @@ pub async fn proxy_handler(
} }
} }
_ => { _ => {
error!( // Silent reject for unsupported formats (likely scanning attempts)
"Unsupported file format for: {} (full path: {})", return Err(ErrorNotFound("File not found"));
base_filename, requested_res
);
return Err(ErrorInternalServerError("Unsupported file format"));
} }
}, },
}; };

View File

@@ -22,11 +22,11 @@ pub async fn universal_handler(
return Ok(response); return Ok(response);
} }
// Базовая проверка безопасности // Базовая проверка безопасности (молча отклоняет сканы)
let security_config = SecurityConfig::default(); let security_config = SecurityConfig::default();
if let Err(error) = security_config.validate_request(&req) { if security_config.validate_request(&req).is_err() {
warn!("Security validation failed: {}", error); // Silent reject for scan attempts - return 404 instead of logging
return Err(error); return Ok(HttpResponse::NotFound().finish());
} }
// Проверка upload лимитов только для POST запросов // Проверка upload лимитов только для POST запросов

View File

@@ -95,34 +95,45 @@ impl SecurityConfig {
Ok(()) Ok(())
} }
/// Проверяет путь на подозрительные паттерны /// Проверяет путь на подозрительные паттерны (молча отклоняет сканы)
pub fn check_suspicious_patterns(&self, path: &str) -> bool { pub fn check_suspicious_patterns(&self, path: &str) -> bool {
let suspicious_patterns = [ let suspicious_patterns = [
"/admin", // WordPress scanning patterns
"/wp-admin", "/wp-admin",
"/wp-includes/",
"/wp-content/",
"/wp-login.php",
"/wp-config.php",
"/xmlrpc.php",
"/wlwmanifest.xml",
"/wp-json/",
"/wordpress/",
// Admin panels
"/admin",
"/phpmyadmin", "/phpmyadmin",
"/cpanel",
"/plesk",
// Config & sensitive files
"/.env", "/.env",
"/config", "/config",
"/.git", "/.git",
"/backup", "/backup",
"/db", "/db",
"/sql", "/sql",
"/xmlrpc.php", "/.htaccess",
"/wp-login.php", "/web.config",
"/wp-config.php", // XSS & injection patterns
"script>", "script>",
"<iframe", "<iframe",
"javascript:", "javascript:",
"data:", "data:",
"eval(",
]; ];
let path_lower = path.to_lowercase(); let path_lower = path.to_lowercase();
for pattern in &suspicious_patterns { for pattern in &suspicious_patterns {
if path_lower.contains(pattern) { if path_lower.contains(pattern) {
warn!( // Silent reject - no logging for scan attempts
"Suspicious pattern detected in path: {} (pattern: {})",
path, pattern
);
return true; return true;
} }
} }