From 2df47dc461f9571fbe001c6ef67be573165fde7c Mon Sep 17 00:00:00 2001 From: TheOnlyMace <0815cracky@gmail.com> Date: Tue, 13 Jan 2026 23:04:05 +0100 Subject: [PATCH] Enhance security and configuration of contact form: Added Content Security Policy and Strict-Transport-Security headers in .htaccess for improved security. Updated error handling to use a single 404.php for various error codes. Removed deprecated config.php and composer.json files, and implemented IP address detection for better security. Added honeypot field for bot protection in contact form and improved session security settings in functions.php. --- public/composer.json => composer.json | 0 {public => docs}/KONTAKTFORMULAR-STATUS.md | 0 {public => docs}/README-EMAIL-SETUP.md | 0 {public => docs}/README-OPTIMIZATION.md | 0 {public => docs}/README-STRUCTURE.md | 0 public/.htaccess | 33 +++++++++- public/404.php | 73 ++++++++++++++++++++++ public/500.php | 73 ++++++++++++++++++++++ public/assets/js/contact.js | 3 - public/{ => config}/config.php | 0 public/contact-handler.php | 34 ++++++++-- public/contact.php | 6 +- public/includes/functions.php | 23 ++++++- {public => scripts}/test-email.php | 0 14 files changed, 233 insertions(+), 12 deletions(-) rename public/composer.json => composer.json (100%) rename {public => docs}/KONTAKTFORMULAR-STATUS.md (100%) rename {public => docs}/README-EMAIL-SETUP.md (100%) rename {public => docs}/README-OPTIMIZATION.md (100%) rename {public => docs}/README-STRUCTURE.md (100%) create mode 100644 public/404.php create mode 100644 public/500.php rename public/{ => config}/config.php (100%) rename {public => scripts}/test-email.php (100%) diff --git a/public/composer.json b/composer.json similarity index 100% rename from public/composer.json rename to composer.json diff --git a/public/KONTAKTFORMULAR-STATUS.md b/docs/KONTAKTFORMULAR-STATUS.md similarity index 100% rename from public/KONTAKTFORMULAR-STATUS.md rename to docs/KONTAKTFORMULAR-STATUS.md diff --git a/public/README-EMAIL-SETUP.md b/docs/README-EMAIL-SETUP.md similarity index 100% rename from public/README-EMAIL-SETUP.md rename to docs/README-EMAIL-SETUP.md diff --git a/public/README-OPTIMIZATION.md b/docs/README-OPTIMIZATION.md similarity index 100% rename from public/README-OPTIMIZATION.md rename to docs/README-OPTIMIZATION.md diff --git a/public/README-STRUCTURE.md b/docs/README-STRUCTURE.md similarity index 100% rename from public/README-STRUCTURE.md rename to docs/README-STRUCTURE.md diff --git a/public/.htaccess b/public/.htaccess index a07a21c..9238bf3 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -8,6 +8,12 @@ Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()" + + # Content Security Policy - Schutz vor XSS und Code-Injection + Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://cdn.hexahost.de data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" + + # Strict-Transport-Security (HSTS) - Erzwingt HTTPS + Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # HTTPS erzwingen (falls SSL verfügbar) @@ -48,6 +54,16 @@ Deny from all +# Config-Verzeichnis schützen + + RewriteRule ^config/ - [F,L] + + +# Includes-Verzeichnis schützen (direkter Zugriff verhindern) + + RewriteRule ^includes/ - [F,L] + + # Logs-Verzeichnis schützen RewriteRule ^logs/ - [F,L] @@ -95,14 +111,25 @@ # Fehlerbehandlung -ErrorDocument 404 /404.html -ErrorDocument 500 /500.html +ErrorDocument 400 /404.php +ErrorDocument 401 /404.php +ErrorDocument 403 /404.php +ErrorDocument 404 /404.php +ErrorDocument 500 /500.php +ErrorDocument 502 /500.php +ErrorDocument 503 /500.php # Verzeichnis-Listing deaktivieren Options -Indexes # Datei-Zugriff beschränken - + Order Allow,Deny Deny from all + + +# Spezifische Ausnahmen für benötigte XML-Dateien + + Order Allow,Deny + Allow from all \ No newline at end of file diff --git a/public/404.php b/public/404.php new file mode 100644 index 0000000..39dcdfe --- /dev/null +++ b/public/404.php @@ -0,0 +1,73 @@ + + +
+
+
+
+
404
+

Seite nicht gefunden

+

Die angeforderte Seite existiert leider nicht oder wurde verschoben.

+ +
+
+
+
+ + + + diff --git a/public/500.php b/public/500.php new file mode 100644 index 0000000..e5c6ea6 --- /dev/null +++ b/public/500.php @@ -0,0 +1,73 @@ + + +
+
+
+
+
500
+

Interner Serverfehler

+

Es ist ein unerwarteter Fehler aufgetreten. Wir arbeiten bereits an der Lösung.

+ +
+
+
+
+ + + + diff --git a/public/assets/js/contact.js b/public/assets/js/contact.js index 0825812..a27478b 100644 --- a/public/assets/js/contact.js +++ b/public/assets/js/contact.js @@ -51,9 +51,6 @@ // Get form data const formData = new FormData(form); - // Add honeypot field (hidden field for bot protection) - formData.append('website', ''); // Honeypot field - // Basic validation const data = {}; for (let [key, value] of formData.entries()) { diff --git a/public/config.php b/public/config/config.php similarity index 100% rename from public/config.php rename to public/config/config.php diff --git a/public/contact-handler.php b/public/contact-handler.php index f98749f..a828f9e 100644 --- a/public/contact-handler.php +++ b/public/contact-handler.php @@ -10,7 +10,7 @@ if (session_status() === PHP_SESSION_NONE) { } // Konfiguration laden -require_once 'config.php'; +require_once 'config/config.php'; // Konfiguration verwenden $config = getHexaHostConfig(); @@ -113,6 +113,32 @@ function sanitizeInput($input) { return htmlspecialchars(strip_tags(trim($input)), ENT_QUOTES, 'UTF-8'); } +// Sichere IP-Adressen-Erkennung (auch hinter Proxies/Cloudflare) +function getClientIP() { + $ip_keys = [ + 'HTTP_CF_CONNECTING_IP', // Cloudflare + 'HTTP_X_FORWARDED_FOR', // Proxy + 'HTTP_X_REAL_IP', // Nginx Proxy + 'REMOTE_ADDR' // Standard + ]; + + foreach ($ip_keys as $key) { + if (!empty($_SERVER[$key])) { + // Bei X-Forwarded-For kann eine Liste von IPs kommen + $ip = explode(',', $_SERVER[$key])[0]; + $ip = trim($ip); + + // Validiere IP-Format + if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { + return $ip; + } + } + } + + // Fallback auf REMOTE_ADDR (auch private IPs für lokale Entwicklung) + return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; +} + // SMTP E-Mail-Versand mit PHPMailer function sendEmail($data) { global $config; @@ -268,7 +294,7 @@ function generateEmailHTML($data) {
IP-Adresse:
-
' . $_SERVER['REMOTE_ADDR'] . '
+
' . htmlspecialchars(getClientIP()) . '
@@ -311,7 +337,7 @@ function generateEmailText($data) { $text .= "----------\n"; $text .= $data['message'] . "\n\n"; - $text .= "IP-Adresse: " . $_SERVER['REMOTE_ADDR'] . "\n"; + $text .= "IP-Adresse: " . getClientIP() . "\n"; $text .= "Zeitstempel: " . date('d.m.Y H:i:s') . "\n\n"; $text .= "---\n"; @@ -334,7 +360,7 @@ try { } // Rate Limiting Check - $client_ip = $_SERVER['REMOTE_ADDR']; + $client_ip = getClientIP(); if (!checkRateLimit($client_ip)) { http_response_code(429); echo json_encode([ diff --git a/public/contact.php b/public/contact.php index 8a6527a..c3c3ed8 100644 --- a/public/contact.php +++ b/public/contact.php @@ -97,6 +97,10 @@ includeHeader($page_title, $page_description, $current_page, $additional_scripts
+ +
@@ -143,7 +147,7 @@ includeHeader($page_title, $page_description, $current_page, $additional_scripts
diff --git a/public/includes/functions.php b/public/includes/functions.php index b944d8d..912433d 100644 --- a/public/includes/functions.php +++ b/public/includes/functions.php @@ -3,9 +3,30 @@ * Helper functions for HexaHost.de */ -// Start session for CSRF token +// Sichere Session-Konfiguration if (session_status() === PHP_SESSION_NONE) { + // Session-Cookie-Sicherheit + ini_set('session.cookie_httponly', 1); + ini_set('session.cookie_secure', isset($_SERVER['HTTPS']) ? 1 : 0); + ini_set('session.cookie_samesite', 'Strict'); + ini_set('session.use_strict_mode', 1); + ini_set('session.use_only_cookies', 1); + session_start(); + + // Session-ID regenerieren bei Login/wichtigen Aktionen (Schutz vor Session Fixation) + if (!isset($_SESSION['initiated'])) { + session_regenerate_id(true); + $_SESSION['initiated'] = true; + } +} + +// PHP Error Display in Produktion deaktivieren +if (!defined('DEBUG_MODE') || !DEBUG_MODE) { + ini_set('display_errors', 0); + ini_set('display_startup_errors', 0); + error_reporting(E_ALL); + ini_set('log_errors', 1); } /** diff --git a/public/test-email.php b/scripts/test-email.php similarity index 100% rename from public/test-email.php rename to scripts/test-email.php