ADR-004 - Architektura systemu bezpieczeństwa
ADR-004: Architektura systemu bezpieczeństwa
Dział zatytułowany „ADR-004: Architektura systemu bezpieczeństwa”Kompleksowa architektura bezpieczeństwa dla XOOPS CMS chroniącej przed nowoczesnymi zagrożeniami.
Accepted - Warstwa bezpieczeństwa rdzenia od XOOPS 2.5
Kontekst
Dział zatytułowany „Kontekst”Oświadczenie problemu
Dział zatytułowany „Oświadczenie problemu”XOOPS potrzebuje solidnego systemu bezpieczeństwa, który:
- Chroni przed typowymi lukami w zabezpieczeniach internetowych (OWASP Top 10)
- Zapewnia dokładną kontrolę uprawnień na wszystkich modułach
- Umożliwia bezpieczne uwierzytelnianie użytkowników z nowoczesnymi standardami
- Zapobiega naruszeniom danych i nieautoryzowanemu dostępowi
- Obsługuje wielopoziomową kontrolę dostępu (admin, moderator, użytkownik, gość)
- Integruje się ze wszystkimi modułami bezproblemowo
Bieżące zagrożenia
Dział zatytułowany „Bieżące zagrożenia”Nowoczesne ataki internetowe obejmują:
- Wstrzyknięcie SQL - Złośliwy SQL w danych wejściowych użytkownika
- XSS (Cross-Site Scripting) - Wstrzyknięty JavaScript na stronach
- CSRF (Cross-Site Request Forgery) - Nieautoryzowane przesyłanie formularzy
- Obejście uwierzytelniania - Słabe obsługiwanie sesji/hasła
- Obejście autoryzacji - Eskalacja uprawnień
- Ujawnienie danych - Poufne dane w adresach URL, dziennikach lub cache
Wymagania bezpieczeństwa XOOPS
Dział zatytułowany „Wymagania bezpieczeństwa XOOPS”- Uwierzytelnianie użytkownika i zarządzanie sesją
- Kontrola dostępu oparta na rolach (RBAC)
- System uprawnień dla modułów i obiektów
- Walidacja danych wejściowych i escaping danych wyjściowych
- Ochrona przed typowymi atakami
- Rejestrowanie zdarzeń bezpieczeństwa
- Bezpieczne obsługiwanie haseł
- Ochrona tokenu CSRF
Decyzja
Dział zatytułowany „Decyzja”Architektura bezpieczeństwa rdzenia
Dział zatytułowany „Architektura bezpieczeństwa rdzenia”graph TB subgraph "Warstwa uwierzytelniania" A["Uwierzytelnianie użytkownika<br/>(Logowanie/Sesje)"] B["Zarządzanie sesją<br/>(Tokeny/Ciasteczka)"] C["Bezpieczeństwo hasła<br/>(Hashing/Sól)"] end
subgraph "Warstwa autoryzacji" D["Zarządzanie rolami<br/>(Admin/Użytkownik/Gość)"] E["System uprawnień<br/>(Poziom modułu)"] F["Uprawnienia obiektu<br/>(Poziom elementu)"] end
subgraph "Warstwa ochrony" G["Walidacja wejścia<br/>(Typ/Format)"] H["Escaping wyjścia<br/>(HTML/JavaScript)"] I["Ochrona CSRF<br/>(Weryfikacja tokenu)"] end
subgraph "Warstwa monitorowania" J["Rejestrowanie audytu<br/>(Zdarzenia bezpieczeństwa)"] K["Ograniczenie szybkości<br/>(Brute Force)"] L["Detekcja włamań<br/>(Podejrzana aktywność)"] end
A --> B A --> C D --> E E --> F G --> I H --> I J --> K K --> LKomponenty bezpieczeństwa
Dział zatytułowany „Komponenty bezpieczeństwa”1. System uwierzytelniania
Dział zatytułowany „1. System uwierzytelniania”Proces logowania użytkownika:
<?php// 1. Waliduj poświadczenia$user = $userHandler->findByLogin($username);if (!$user || !password_verify($password, $user->getVar('pass'))) { throw new AuthenticationException('Nieprawidłowe poświadczenia');}
// 2. Sprawdź czy konto jest aktywneif (!$user->getVar('uactive')) { throw new AuthenticationException('Konto nieaktywne');}
// 3. Utwórz bezpieczną sesjęsession_regenerate_id(true);$_SESSION['uid'] = $user->getVar('uid');$_SESSION['token'] = bin2hex(random_bytes(32));$_SESSION['created'] = time();
// 4. Zaloguj logowanie$this->auditLog('USER_LOGIN', $user->getVar('uid'));Bezpieczeństwo hasła:
<?php// Użyj password_hash (nie MD5 ani SHA1)$hashed = password_hash($password, PASSWORD_BCRYPT, [ 'cost' => 12, // Wysoki koszt = powolny brute force]);
// Weryfikuj hasłoif (!password_verify($inputPassword, $hashed)) { throw new Exception('Nieprawidłowe hasło');}
// Ponownie zahashuj jeśli algorytm lub koszt się zmieniłif (password_needs_rehash($hashed, PASSWORD_BCRYPT, ['cost' => 12])) { $newHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); $user->setVar('pass', $newHash); $userHandler->insert($user);}2. Zarządzanie sesją
Dział zatytułowany „2. Zarządzanie sesją”Bezpieczne obsługiwanie sesji:
<?php// Konfiguracja sesjiini_set('session.cookie_httponly', true); // Brak dostępu JSini_set('session.cookie_secure', true); // Tylko HTTPSini_set('session.cookie_samesite', 'Strict'); // Ochrona CSRFini_set('session.gc_maxlifetime', 3600); // 1 godzina timeoutini_set('session.sid_length', 64); // 64-znakowy ID sesji
// Waliduj sesjęfunction validateSession() { // Sprawdź timeout if (time() - $_SESSION['created'] > 3600) { session_destroy(); throw new SessionExpiredException(); }
// Waliduj user agent (zapobiegaj przejęciu sesji) if ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) { throw new SessionInvalidException(); }
// Waliduj IP (opcjonalne, może być zbyt surowe) if (!in_array($_SERVER['REMOTE_ADDR'], $_SESSION['ips'])) { $_SESSION['ips'][] = $_SERVER['REMOTE_ADDR']; }}3. Autoryzacja (RBAC)
Dział zatytułowany „3. Autoryzacja (RBAC)”Kontrola dostępu oparta na rolach:
<?phpclass XoopsUser { public function hasPermission(string $permissionName): bool { // Pobierz grupy użytkowników $groups = $this->getGroups();
// Sprawdź czy jakakolwiek grupa ma uprawnienie foreach ($groups as $groupId) { if ($this->checkGroupPermission($groupId, $permissionName)) { return true; } }
return false; }
/** * Grupy użytkowników i ich uprawnienia * Admin: Pełny dostęp * Moderator: Zarządzanie treścią * User: Utwórz własną treść * Guest: Dostęp tylko do odczytu */ private function checkGroupPermission(int $groupId, string $permission): bool { $permissions = [ 1 => ['admin_access'], // Grupa Admin 2 => ['moderate_content', 'edit_own'], // Grupa Moderator 3 => ['create_content', 'edit_own'], // Grupa User 4 => [], // Grupa Guest (brak uprawnień) ];
return in_array($permission, $permissions[$groupId] ?? []); }}4. Walidacja wejścia
Dział zatytułowany „4. Walidacja wejścia”Zapobiegaj wstrzyknięciom SQL i błędom typów:
<?php// Zawsze używaj prepared statements$sql = 'SELECT * FROM users WHERE id = ?';$result = $db->query($sql, [$userId]); // ✅ Bezpieczne
// Walidacja wejściafunction validateUserInput(array $data): array{ return [ 'email' => filter_var($data['email'] ?? '', FILTER_VALIDATE_EMAIL), 'age' => filter_var($data['age'] ?? 0, FILTER_VALIDATE_INT), 'website' => filter_var($data['website'] ?? '', FILTER_VALIDATE_URL), 'title' => substr(trim($data['title'] ?? ''), 0, 255), ];}
// Klasa bezpiecznego wejścia XOOPS$safe = \Xmf\Request::getHtmlRequest('var_name', '');$int = \Xmf\Request::getInt('page', 1);5. Escaping danych wyjściowych
Dział zatytułowany „5. Escaping danych wyjściowych”Zapobiegaj atakom XSS:
<?php// W szablonach PHPecho htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// W szablonach Smarty (automatyczne escaping)<{$user_input}> {* Escaped domyślnie *}<{$html|escape:false}> {* Tylko gdy potrzeba *}
// Kontekst JavaScript<script>var message = "<{$userMessage|escape:'javascript'}>";</script>
// Kontekst URL<a href="<{$url|escape:'url'}>">Link</a>6. Ochrona CSRF
Dział zatytułowany „6. Ochrona CSRF”Zapobieganie Cross-Site Request Forgery:
<?php// Generuj token CSRFsession_start();if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32));}
// W formularzach<form method="POST"> <input type="hidden" name="csrf_token" value="<{$csrf_token}>"> <button type="submit">Prześlij</button></form>
// Waliduj tokenif ($_SERVER['REQUEST_METHOD'] === 'POST') { if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) { // Przetwórz formularz } else { throw new InvalidTokenException('Token CSRF nieprawidłowy'); }}Konsekwencje
Dział zatytułowany „Konsekwencje”Pozytywne efekty
Dział zatytułowany „Pozytywne efekty”- Kompleksowa ochrona - Obejmuje główne klasy luk w zabezpieczeniach
- Bezpieczeństwo warstwowe - Wiele warstw obrony
- Elastyczny RBAC - Dokładna kontrola uprawnień
- Ścieżka audytu - Śledź zdarzenia bezpieczeństwa
- Standard branżowy - Wyrównane z rekomendacjami OWASP
- Integracja modułów - Łatwe dla modułów korzystania z interfejsów API bezpieczeństwa
Negatywne efekty
Dział zatytułowany „Negatywne efekty”- Złożoność - Potrzeba więcej kodu i konfiguracji
- Wydajność - Hashing i walidacja dodają narzut
- Doświadczenie użytkownika - Bezpieczeństwo czasami nieporęczne
- Konserwacja - Wymaga bieżących aktualizacji bezpieczeństwa
- Wymagane szkolenie - Programiści muszą postępować zgodnie z praktykami
Zagrożenia i łagodzenie
Dział zatytułowany „Zagrożenia i łagodzenie”| Zagrożenie | Ważność | Łagodzenie |
|---|---|---|
| Programista ignoruje bezpieczeństwo | Wysokie | Przegląd kodu, szkolenie bezpieczeństwa |
| Odkryto nowe luki | Średnie | Regularne audyty bezpieczeństwa, aktualizacje |
| Wpływ na wydajność | Niskie | Optymalizuj gorące ścieżki, buforowanie |
| Zbyt złożone uprawnienia | Średnie | Jasna dokumentacja, przykłady |
Najlepsze praktyki bezpieczeństwa
Dział zatytułowany „Najlepsze praktyki bezpieczeństwa”Dla programistów modułów
Dział zatytułowany „Dla programistów modułów”<?php// ✅ RÓB: Użyj prepared statements$result = $db->prepare('SELECT * FROM table WHERE id = ?')->execute([$id]);
// ❌ NIE RÓB: Łącz zapytania$result = $db->query("SELECT * FROM table WHERE id = $id");
// ✅ RÓB: Escape wyjścieecho htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
// ❌ NIE RÓB: Wypisuj surowe dane użytkownikaecho $user_input;
// ✅ RÓB: Sprawdzaj uprawnieniaif (!$user->hasPermission('edit_content')) { throw new PermissionException();}
// ❌ NIE RÓB: Ufaj rolom użytkownika bezpośrednioif ($_POST['is_admin']) { // Uczyń użytkownika adminem - LUKA BEZPIECZEŃSTWA!}
// ✅ RÓB: Waliduj typy wejścia$page = (int)$_GET['page'];
// ❌ NIE RÓB: Używaj niezaufanych wartości bezpośrednio$sql .= " LIMIT " . $_GET['limit'];Rozważane alternatywy
Dział zatytułowany „Rozważane alternatywy”OAuth/OpenID Connect
Dział zatytułowany „OAuth/OpenID Connect”Dlaczego nie wybrano początkowo: Za złożone dla środowiska hostingu współdzielonego, ale dobre dla przyszłej integracji z zewnętrznymi systemami auth.
Uwierzytelnianie dwuskładnikowe (2FA)
Dział zatytułowany „Uwierzytelnianie dwuskładnikowe (2FA)”Status: Akceptowana jako rozszerzenie, nie jako wymóg rdzenia, patrz ADR-006
Ciasteczka sesji tylko HTTP
Dział zatytułowany „Ciasteczka sesji tylko HTTP”Status: Wdrożone - uniemożliwia dostęp JavaScript do danych sesji
Powiązane decyzje
Dział zatytułowany „Powiązane decyzje”- ADR-001: Architektura modularna - Moduły implementują bezpieczeństwo
- ADR-005: System uprawnień modułu
- ADR-006: Uwierzytelnianie dwuskładnikowe (przyszłość)
Odwołania
Dział zatytułowany „Odwołania”Standardy bezpieczeństwa
Dział zatytułowany „Standardy bezpieczeństwa”Bezpieczeństwo PHP
Dział zatytułowany „Bezpieczeństwo PHP”Narzędzia
Dział zatytułowany „Narzędzia”Lista kontrolna wdrażania
Dział zatytułowany „Lista kontrolna wdrażania”- System uwierzytelniania użytkownika
- Zarządzanie sesją
- Hashing hasła (bcrypt)
- Kontrola dostępu oparta na rolach
- Uprawnienia modułu
- Framework walidacji wejścia
- Escaping wyjścia (PHP + Smarty)
- Ochrona tokenu CSRF
- Rejestrowanie audytu bezpieczeństwa
- Ograniczenie szybkości
- Nagłówki bezpieczeństwa
Historia wersji
Dział zatytułowany „Historia wersji”| Wersja | Data | Zmiany |
|---|---|---|
| 1.0.0 | 2024-01-28 | Dokument początkowy |
#xoops #adr #bezpieczeństwo #architektura #uwierzytelnianie #autoryzacja #rbac