Fix security vulnerabilities, remove dead code, and improve code quality
- Fix path traversal with realpath() validation in getPage() and executePhpFile() - Remove insecure JWT secret fallback, require JWT_SECRET env var - Fix IP spoofing by only trusting proxy headers from configured proxies - Add Secure/HttpOnly/SameSite flags to all cookies - Use env var for debug mode instead of hardcoded true - Fix operator precedence bug in MQTTTracker track_user_flows check - Remove dead code: duplicate is_dir() block, unused scanForPageNames() - Remove htmlspecialchars() from filesystem path operations - Remove duplicate require_once calls and redundant autoloader includes - Fix unclosed </div> in getDirectoryListing() - Escape breadcrumb titles and add lang param to search result URLs - Make language prefixes dynamic from config instead of hardcoded nl|en - Make HTML lang attribute dynamic, add go_to translation key - Add aria-label/aria-expanded to sidebar toggle for accessibility - Fix event listener leak in app.js using event delegation - Remove console.log from production code - Update guides (NL/EN) with sidebar toggle documentation - Add TODO.md documenting all identified improvements
This commit is contained in:
@@ -67,7 +67,13 @@ class MQTTTracker
|
||||
}
|
||||
|
||||
$sessionId = uniqid('cms_', true);
|
||||
setcookie('cms_session_id', $sessionId, time() + $this->config['session_timeout'], '/');
|
||||
setcookie('cms_session_id', $sessionId, [
|
||||
'expires' => time() + $this->config['session_timeout'],
|
||||
'path' => '/',
|
||||
'secure' => isset($_SERVER['HTTPS']),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
return $sessionId;
|
||||
}
|
||||
|
||||
@@ -112,8 +118,20 @@ class MQTTTracker
|
||||
];
|
||||
|
||||
// Update tracking cookies
|
||||
setcookie('cms_previous_page', $pageUrl, time() + $this->config['session_timeout'], '/');
|
||||
setcookie('cms_page_timestamp', time(), time() + $this->config['session_timeout'], '/');
|
||||
setcookie('cms_previous_page', $pageUrl, [
|
||||
'expires' => time() + $this->config['session_timeout'],
|
||||
'path' => '/',
|
||||
'secure' => isset($_SERVER['HTTPS']),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
setcookie('cms_page_timestamp', (string) time(), [
|
||||
'expires' => time() + $this->config['session_timeout'],
|
||||
'path' => '/',
|
||||
'secure' => isset($_SERVER['HTTPS']),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
|
||||
$this->publishMessage('page_visit', $pageData);
|
||||
}
|
||||
@@ -128,7 +146,7 @@ class MQTTTracker
|
||||
|
||||
private function trackUserFlow(): void
|
||||
{
|
||||
if (!$this->config['track_user_flows'] ?? true) {
|
||||
if (!($this->config['track_user_flows'] ?? true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,22 +228,30 @@ class MQTTTracker
|
||||
|
||||
private function getClientIp(): string
|
||||
{
|
||||
// Check Cloudflare header first if present
|
||||
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
|
||||
return $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
}
|
||||
|
||||
$ipKeys = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'];
|
||||
// Only trust REMOTE_ADDR by default - proxy headers can be spoofed
|
||||
// Configure trusted_proxies in config to enable proxy header support
|
||||
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
||||
$trustedProxies = $this->config['trusted_proxies'] ?? [];
|
||||
|
||||
foreach ($ipKeys as $key) {
|
||||
if (!empty($_SERVER[$key])) {
|
||||
$ips = explode(',', $_SERVER[$key]);
|
||||
// Return the first IP in the list (client IP)
|
||||
return trim($ips[0]);
|
||||
if (!empty($trustedProxies) && in_array($remoteAddr, $trustedProxies)) {
|
||||
// Only trust proxy headers when request comes from a known proxy
|
||||
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
|
||||
return $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
}
|
||||
|
||||
$ipKeys = ['HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP'];
|
||||
foreach ($ipKeys as $key) {
|
||||
if (!empty($_SERVER[$key])) {
|
||||
$ips = explode(',', $_SERVER[$key]);
|
||||
$ip = trim($ips[0]);
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||
return $ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
||||
return $remoteAddr;
|
||||
}
|
||||
|
||||
private function publishMessage(string $topic, array $data): void
|
||||
|
||||
Reference in New Issue
Block a user