🔒 Sicherheits- & Clean-Code-Richtlinien

Verbindliche Entwicklungsstandards für MY-Province.de

Version 1.0 • Stand: 18. April 2026 • Autor: Guido Seifert

Projekt-Übersicht

Diese Richtlinien dokumentieren sämtliche Sicherheitsmaßnahmen und Code-Standards, die für MY-Province.de (Stand 18. April 2026) eingeführt wurden. Sie gelten als verbindlich für alle zukünftigen Änderungen am Projekt.

38+
Zusätzliche Sicherheitsmaßnahmen eingerichtet
12
Sicherheitsrichtlinien
8
Clean-Code-Regeln
6
Code-Style-Standards
Kontext: Die Sicherheitsstandards dieser Website wurden umfassend an ein durchgängiges Sicherheitskonzept angepasst. Alle hier beschriebenen Richtlinien basieren auf den OWASP Top 10 und bewährten Best Practices für sichere Webentwicklung.

Sicherheitsrichtlinien

Basierend auf den OWASP Top 10 und den spezifischen Anforderungen des Projekts.

Kritisch Authentifizierung

Jede PHP-Datei, die Daten verarbeitet oder anzeigt, MUSS eine Session-Prüfung enthalten. Keine Ausnahmen.

Kritisch SQL Injection

Prepared Statements oder (int)-Cast für ALLE Datenbankabfragen. Kein String-Concat mit User-Input.

Hoch XSS-Prävention

Alle Ausgaben von Datenbankinhalten oder Benutzereingaben mit htmlspecialchars() escapen.

Hoch CSRF-Schutz

Datenverändernde Operationen benötigen CSRF-Tokens. AJAX-Calls müssen POST verwenden.

Mittel Header Injection

E-Mail-Header dürfen keine unkontrollierten Benutzereingaben enthalten. CRLF-Prüfung obligatorisch.

Mittel Verzeichnisschutz

Sensible Verzeichnisse (config/, tools/, Legacy-Code) müssen per .htaccess gesperrt sein.


Authentifizierung & Session-Management

Pflicht-Auth-Check für Admin-Dateien

Jede PHP-Datei im admin/-Verzeichnis MUSS diesen Block enthalten:

<?php
session_start();
if (!isset($_SESSION['ZUGANG']) || !isset($_SESSION['USER'])) {
    http_response_code(403);
    die('Zugriff verweigert');
}
?>

Dashboard-Dateien (SessionManager)

require_once __DIR__ . '/core/classes/SessionManager.php';
SessionManager::start();
if (!SessionManager::isLoggedIn()) {
    header('Location: /dashboard/public/login.php');
    exit;
}

Session-Konfiguration

EinstellungWertZweck
session.cookie_httponlytrueJavaScript-Zugriff auf Session-Cookie verhindern
session.cookie_securetrueCookie nur über HTTPS senden
session.cookie_samesiteStrictCSRF-Schutz auf Cookie-Ebene
session_regenerate_id(true)Nach LoginSession-Fixation verhindern
Rate Limiting5 Versuche / 5 Min.Brute-Force-Schutz
Passwort-HashingPASSWORD_ARGON2IDModerner Hash-Algorithmus
ACHTUNG: $_SESSION['ZUGANG'] wird als bin2hex(random_bytes(32)) gesetzt (String, nicht Boolean). Auth-Checks müssen !isset() verwenden, NICHT !== true.

XSS-Prävention (Cross-Site Scripting)

Goldene Regel

Jede Variable, die in HTML-Kontext ausgegeben wird, MUSS escaped werden:

// ❌ VERBOTEN – Direkte Ausgabe
echo $row['NAME'];
echo $_POST['field'];
value="<?php echo $row['EMAIL']; ?>"

// ✅ RICHTIG – Escaped Ausgabe
echo htmlspecialchars($row['NAME'] ?? '', ENT_QUOTES, 'UTF-8');
value="<?php echo htmlspecialchars($row['EMAIL'] ?? '', ENT_QUOTES, 'UTF-8'); ?>"

Anwendungsbereiche

KontextMethode
HTML-Inhalthtmlspecialchars($var, ENT_QUOTES, 'UTF-8')
HTML-Attributehtmlspecialchars($var, ENT_QUOTES, 'UTF-8')
IDs in Attributen(int)$var für numerische IDs
JavaScriptjson_encode($var)
URLsurlencode($var)

SQL-Injection-Schutz

Prepared Statements (bevorzugt)

// ✅ Dashboard – PDO Prepared Statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$userId]);

// ✅ Admin CRM – Integer-Cast für IDs
$id = (int)($_POST['ID'] ?? 0);
$result = $db->select('CLIENT', '*', "ID = '".$id."'");

Verbotene Muster

// ❌ VERBOTEN – String-Konkatenation mit User-Input
$result = $db->select("CLIENT", "*", "ID = '".$_POST['id']."'");
$sql = "SELECT * FROM users WHERE name = '" . $username . "'";

// ❌ VERBOTEN – Unkontrollierte DB-Werte in Queries
$result = $db->select("SECTOR", "*", "ID = '".$row['SECTOR_TYP']."'");
// ✅ RICHTIG – Cast auch bei DB-Werten (Second-Order SQLi)
$result = $db->select("SECTOR", "*", "ID = '".(int)$row['SECTOR_TYP']."'");
Second-Order SQL Injection: Auch Daten aus der Datenbank können manipuliert sein. Numerische Werte aus DB-Ergebnissen müssen mit (int) gecastet werden, bevor sie in weitere Queries einfließen.

Verzeichnis- & Dateischutz

Geschützte Verzeichnisse

VerzeichnisSchutzMethode
config/Vollständig gesperrt.htaccess: Deny from all
dashboard/config/Vollständig gesperrt.htaccess: Deny from all
dashboard/tools/Vollständig gesperrt.htaccess: Deny from all
survey/PHP-Dateien gesperrt.htaccess: Files *.php Deny
web-work/Legacy – gesperrt.htaccess: Deny from all
admin/mysql/Backend deaktiviertmysql.php: die()

.htaccess-Hinweise

WICHTIG: Die Apache-Direktive <Files> matched NUR Dateinamen, KEINE Pfade! <Files "config/*"> funktioniert NICHT. Stattdessen .htaccess direkt ins zu schützende Verzeichnis legen.

Dateitype-Blockierung (Root .htaccess)

# Gefährliche Dateitypen blockieren
<FilesMatch "\.(sql|bak|old|log|env)$">
    Deny from all
</FilesMatch>

# Sensible PHP-Dateien blockieren
<FilesMatch "^(mysql|myDB|database|config)\.(php|inc)$">
    Deny from all
</FilesMatch>

HTTP-Security-Headers

HeaderWertSchutz gegen
X-Frame-OptionsDENYClickjacking
X-Content-Type-OptionsnosniffMIME-Type-Sniffing
X-XSS-Protection1; mode=blockReflektiertes XSS (Legacy-Browser)
Referrer-Policystrict-origin-when-cross-originInformation Leakage
Strict-Transport-Securitymax-age=31536000; includeSubDomainsDowngrade-Angriffe / MITM
Content-Security-Policydefault-src 'self'; ...XSS, Data Injection

E-Mail-Header-Sicherheit

// CRLF-Injection verhindern bei E-Mail-Headern
if (preg_match('/[\r\n%0a%0d]/i', $email)) {
    die('Ungültige Eingabe erkannt.');
}

Clean-Code-Richtlinien

Diese Regeln gelten projektübergreifend und sichern Wartbarkeit, Lesbarkeit und Sicherheit.

1. Separation of Concerns

  • PHP: Nur HTML + PHP-Logik, KEIN CSS oder JavaScript
  • CSS: Alle Styles in separaten .css-Dateien
  • JS: Alle Funktionen in separaten .js-Dateien

2. Keine Inline-Styles

  • Kein style="..." in HTML-Elementen
  • Stattdessen semantische CSS-Klassen nutzen
  • Bestehende Klassen: .feature-card-*, .card-title-white

3. Kein JavaScript in PHP

  • Externe .js-Dateien statt <script>-Blöcke
  • Kein onclick="..." bei neuem Code (Event-Listener)
  • Ausnahme: Legacy-Code mit loadExample()-Pattern

4. Kein CSS in Script-Tags

  • Keine dynamische CSS-Manipulation in JavaScript
  • CSS-Klassen toggle statt .css()-Aufrufe
  • Alle Styles in dedizierte CSS-Dateien auslagern

5. Sichere Defaults

  • display_errors = 0 in Produktion
  • Keine Debug-Ausgaben im Browser
  • Fehler nur ins Error-Log schreiben
  • Passwörter / Tokens nie anzeigen

6. Null-Safe Zugriffe

  • $_POST['key'] ?? 0 mit Null-Coalescing
  • $row['FIELD'] ?? '' für DB-Ergebnisse
  • Keine @-Error-Suppression nutzen

7. DRY – Don't Repeat Yourself

  • Auth-Logic zentral, nicht in jeder Datei neu
  • Gemeinsame Includes: header.php, footer.php
  • Reusable Components in project-components.css

8. Keine toten Dateien

  • Ungenutzte *-old.php-Dateien löschen
  • Debug-Dateien vor Go-Live entfernen
  • Legacy-Verzeichnisse per .htaccess sperren

Code-Style-Richtlinien

PHP-Konventionen

AspektRichtlinieBeispiel
Encoding Immer UTF-8 <meta charset="UTF-8">
Sprache UI + Kommentare auf Deutsch // Benutzer authentifizieren
Variablen camelCase für lokale Variablen $clientId, $resultSector
Klassen PascalCase Database, SessionManager
Konstanten UPPER_SNAKE_CASE DB_HOST, DASHBOARD_INIT
DB-Spalten UPPER_SNAKE_CASE (bestehend) CLIENT_STATUS, SECTOR_TYP
Einrückung Tabs in PHP, Spaces in CSS/JS Konsistent pro Datei
String-Quotes Einfache Quotes bevorzugt 'text' statt "text"

CSS-Namenskonventionen

/* Komponentenbasierte Klassen */
.feature-card-success    /* Grüne Erfolgskarte */
.feature-card-primary    /* Blaue Hauptkarte */
.feature-card-warning    /* Orange Warnkarte */
.feature-card-info       /* Lila Infokarte */

/* Inhaltsklassen */
.card-title-white        /* Weiße Kartentitel */
.card-text-white         /* Weiße Kartentexte */

/* Utility-Klassen */
.responsive-image        /* max-width: 100% */
.hidden                  /* display: none !important */
.text-center             /* Textausrichtung */

Syntax-Highlighting-Klassen

SprachePrefixBeispiel
C#cs-*.cs-keyword, .cs-class, .cs-string
JavaScriptjs-*.js-keyword, .js-function
SQLsql-*.sql-keyword, .sql-string
PHPphp-*.php-keyword, .php-variable

Dateistruktur-Konventionen

<!-- Standard-Seitenstruktur -->
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="...">
    <title>Titel - MyProvince.de</title>
    <link rel="stylesheet" href="/web/css/style.css">
</head>
<body>
    <?php include 'includes/header.php'; ?>
    <main> <!-- Inhalt --> </main>
    <?php include 'includes/footer.php'; ?>
    <script src="/web/js/script.js"></script>
</body>
</html>

JavaScript (AJAX-Pattern)

// ✅ Standard AJAX-Muster für Admin-Operationen
$.ajax({
    type: 'POST',              // IMMER POST für Datenänderungen
    url:  '/admin/api.php',
    data: {
        action:     'update',
        table:      'CLIENT',
        csrf_token: csrfToken,        // CSRF-Token mitsenden
        id:         clientId,
        name:       clientName
    },
    success: function(response) { /* ... */ }
});

Audit-Protokoll

Chronologische Übersicht aller durchgeführten Sicherheitsmaßnahmen.

DatumKategorieMaßnahmeStatus
17.04.2026AuthSession-Prüfung in 10x admin/formular/*.phpErledigt
17.04.2026AuthAuth-Check clientList.php, setting_sectorList.phpErledigt
17.04.2026AuthSessionManager-Auth für db-schema-export.phpErledigt
17.04.2026AuthAuth-Logik Fix: !== true → !isset() (10 Dateien)Erledigt
17.04.2026SQLi(int)-Cast für IDs in Formular-DateienErledigt
17.04.2026SQLiSecond-Order SQLi Fix in clientList.phpErledigt
17.04.2026SQLiPrepared Statements in survey/Erledigt
17.04.2026XSShtmlspecialchars() in allen Formular-AusgabenErledigt
17.04.2026XSSReflected XSS Fix setting_sector_edit.phpErledigt
17.04.2026CRLFHeader-Injection-Schutz contact_process.phpErledigt
17.04.2026Access.htaccess für survey/, web-work/, tools/Erledigt
17.04.2026AccessRoot .htaccess: Kaputte Files-Direktiven entferntErledigt
17.04.2026HeadersHSTS + verbesserte CSP hinzugefügtErledigt
17.04.2026Cleanup6x *-old.php Debug-Dateien gelöschtErledigt
17.04.2026Info LeakTemp-Passwort aus Browser-Anzeige entferntErledigt
17.04.2026Info Leakdebug-image.php deaktiviert (403)Erledigt
17.04.2026DeprecationFILTER_SANITIZE_STRING → htmlspecialchars()Erledigt
18.04.2026XSShtmlspecialchars() in *_edit.php (30+ Felder)Erledigt
18.04.2026Config.gitignore für .vscode/, Logs, TempErledigt

Bekannte offene Punkte