You've already forked Atomcms-edit
fix(security): eliminate remaining critical vulnerabilities
- SystemFixService: removed ALL shell_exec/sudo calls (30+ instances), replaced with safe PHP alternatives (mkdir, chmod, disk_total_space, Artisan calls) - InstallationController: added ALLOWED_SETTINGS whitelist to prevent arbitrary settings manipulation via request data - ExceptionHandler: removed dangerous npm run build execution and hardcoded chown/chmod paths from auto-recovery - AuthController: fixed user enumeration timing attack by running Hash::make() even when user doesn't exist (constant-time comparison) - DDoSDetectionCommand: added IP validation (FILTER_VALIDATE_IP) before blocking to prevent iptables manipulation with spoofed/malicious IPs - trackRequest: now validates IP before storing in cache
This commit is contained in:
@@ -53,41 +53,12 @@ class DDoSDetectionCommand extends Command
|
||||
$data = Cache::get(self::CACHE_KEY_DDOS_TRACKING, []);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->fetchApacheTrafficData();
|
||||
$data = $this->getManualTrackingData();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function fetchApacheTrafficData(): array
|
||||
{
|
||||
$this->warn('Gebruik handmatige IP tracking (geen server logs toegang).');
|
||||
|
||||
return $this->getManualTrackingData();
|
||||
}
|
||||
|
||||
private function tailFile(string $path, int $lines = 100): array
|
||||
{
|
||||
if (! file_exists($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$file = new \SplFileObject($path, 'r');
|
||||
$file->seek(PHP_INT_MAX);
|
||||
$totalLines = $file->key() + 1;
|
||||
|
||||
$startLine = max(0, $totalLines - $lines);
|
||||
$result = [];
|
||||
|
||||
$file->seek($startLine);
|
||||
while (! $file->eof()) {
|
||||
$result[] = rtrim($file->current(), "\r\n");
|
||||
$file->next();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getManualTrackingData(): array
|
||||
{
|
||||
$tracking = Cache::get('manual_ip_tracking', []);
|
||||
@@ -141,6 +112,10 @@ class DDoSDetectionCommand extends Command
|
||||
$newBlocks = [];
|
||||
|
||||
foreach ($suspiciousIps as $ip => $details) {
|
||||
if (! $this->isValidIp($ip)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->error("VERDACHTE IP GEDETECTEERD: {$ip}");
|
||||
$this->table(
|
||||
['Metric', 'Value'],
|
||||
@@ -177,8 +152,19 @@ class DDoSDetectionCommand extends Command
|
||||
Cache::put(self::CACHE_KEY_BLOCKED_IPS, $blockedIps, 3600);
|
||||
}
|
||||
|
||||
private function isValidIp(string $ip): bool
|
||||
{
|
||||
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false;
|
||||
}
|
||||
|
||||
private function blockIp(string $ip): void
|
||||
{
|
||||
if (! $this->isValidIp($ip)) {
|
||||
Log::warning("Attempted to block invalid IP: {$ip}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$escapedIp = escapeshellarg($ip);
|
||||
exec("iptables -A INPUT -s {$escapedIp} -j DROP 2>/dev/null");
|
||||
@@ -192,6 +178,10 @@ class DDoSDetectionCommand extends Command
|
||||
|
||||
public static function trackRequest(string $ip): void
|
||||
{
|
||||
if (! filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tracking = Cache::get('manual_ip_tracking', []);
|
||||
|
||||
if (! isset($tracking[$ip])) {
|
||||
@@ -201,7 +191,7 @@ class DDoSDetectionCommand extends Command
|
||||
$tracking[$ip]['requests'][] = time();
|
||||
$tracking[$ip]['count']++;
|
||||
|
||||
Cache::put('manual_ip_tracking', $tracking, self::TRACKING_DURATION_SECONDS);
|
||||
Cache::put('manual_ip_tracking', $tracking, 300);
|
||||
}
|
||||
|
||||
public static function getBlockedIps(): array
|
||||
@@ -211,6 +201,10 @@ class DDoSDetectionCommand extends Command
|
||||
|
||||
public static function clearBlockedIp(string $ip): void
|
||||
{
|
||||
if (! filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$blocked = Cache::get(self::CACHE_KEY_BLOCKED_IPS, []);
|
||||
$blocked = array_filter($blocked, fn ($blockedIp) => $blockedIp !== $ip);
|
||||
Cache::put(self::CACHE_KEY_BLOCKED_IPS, array_values($blocked), 3600);
|
||||
|
||||
Reference in New Issue
Block a user