Přeskočit na obsah

ADR-004 - Architektura bezpečnostního systému

ADR-004: Architektura bezpečnostního systému

Sekce “ADR-004: Architektura bezpečnostního systému”

Komplexní bezpečnostní architektura pro XOOPS CMS chránící před moderními hrozbami.


Přijato – Základní vrstva zabezpečení od XOOPS 2.5


Prohlášení o problému

Sekce “Prohlášení o problému”

XOOPS potřebuje robustní bezpečnostní systém, který:

  1. Chrání před běžnými webovými chybami (OWASP Top 10)
  2. Poskytuje podrobnou kontrolu oprávnění napříč moduly
  3. Umožňuje bezpečné ověření uživatele s moderními standardy
  4. Zabraňuje úniku dat a neoprávněnému přístupu
  5. Podporuje víceúrovňové řízení přístupu (admin, moderátor, uživatel, host)
  6. Bezproblémová integrace se všemi moduly

Mezi moderní webové útoky patří:

  • SQL Injection - Škodlivý SQL v uživatelském vstupu
  • XSS (Cross-Site Scripting) - Vloženo JavaScript na stránky
  • CSRF (falšování požadavků napříč stránkami) - Neoprávněné odeslání formuláře
  • Autentizační bypass - Slabá obsluha session/password
  • Vynechání autorizace - Eskalace oprávnění
  • Vystavení dat - Citlivá data v adresách URL, protokolech nebo mezipaměti

XOOPS Bezpečnostní požadavky

Sekce “XOOPS Bezpečnostní požadavky”
  1. Autentizace uživatele a správa relací
  2. Řízení přístupu na základě rolí (RBAC)
  3. Systém oprávnění pro moduly a objekty
  4. Ověření vstupu a escapování výstupu
  5. Ochrana proti běžným útokům
  6. Audit logování bezpečnostních událostí
  7. Bezpečná manipulace s hesly
  8. Ochrana tokenu CSRF

Základní bezpečnostní architektura

Sekce “Základní bezpečnostní architektura”
graph TB
subgraph "Authentication Layer"
A["User Authentication<br/>(Login/Sessions)"]
B["Session Management<br/>(Tokens/Cookies)"]
C["Password Security<br/>(Hashing/Salts)"]
end
subgraph "Authorization Layer"
D["Role Management<br/>(Admin/User/Guest)"]
E["Permission System<br/>(Module-level)"]
F["Object Permissions<br/>(Item-level)"]
end
subgraph "Protection Layer"
G["Input Validation<br/>(Type/Format)"]
H["Output Escaping<br/>(HTML/JavaScript)"]
I["CSRF Protection<br/>(Token Validation)"]
end
subgraph "Monitoring Layer"
J["Audit Logging<br/>(Security Events)"]
K["Rate Limiting<br/>(Brute Force)"]
L["Intrusion Detection<br/>(Suspicious Activity)"]
end
A --> B
A --> C
D --> E
E --> F
G --> I
H --> I
J --> K
K --> L

Bezpečnostní komponenty

Sekce “Bezpečnostní komponenty”

1. Autentizační systém

Sekce “1. Autentizační systém”

Proces přihlášení uživatele:

<?php
// 1. Validate credentials
$user = $userHandler->findByLogin($username);
if (!$user || !password_verify($password, $user->getVar('pass'))) {
throw new AuthenticationException('Invalid credentials');
}
// 2. Check if account is active
if (!$user->getVar('uactive')) {
throw new AuthenticationException('Account inactive');
}
// 3. Create secure session
session_regenerate_id(true);
$_SESSION['uid'] = $user->getVar('uid');
$_SESSION['token'] = bin2hex(random_bytes(32));
$_SESSION['created'] = time();
// 4. Log the login
$this->auditLog('USER_LOGIN', $user->getVar('uid'));

Zabezpečení heslem:

<?php
// Use password_hash (not MD5 or SHA1)
$hashed = password_hash($password, PASSWORD_BCRYPT, [
'cost' => 12, // High cost = slow brute force
]);
// Verify password
if (!password_verify($inputPassword, $hashed)) {
throw new Exception('Invalid password');
}
// Rehash if algorithm or cost changed
if (password_needs_rehash($hashed, PASSWORD_BCRYPT, ['cost' => 12])) {
$newHash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
$user->setVar('pass', $newHash);
$userHandler->insert($user);
}

Zabezpečené zpracování relace:

<?php
// Session configuration
ini_set('session.cookie_httponly', true); // No JS access
ini_set('session.cookie_secure', true); // HTTPS only
ini_set('session.cookie_samesite', 'Strict'); // CSRF protection
ini_set('session.gc_maxlifetime', 3600); // 1 hour timeout
ini_set('session.sid_length', 64); // 64-char session ID
// Validate session
function validateSession() {
// Check timeout
if (time() - $_SESSION['created'] > 3600) {
session_destroy();
throw new SessionExpiredException();
}
// Validate user agent (prevent session hijacking)
if ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
throw new SessionInvalidException();
}
// Validate IP (optional, can be too strict)
if (!in_array($_SERVER['REMOTE_ADDR'], $_SESSION['ips'])) {
$_SESSION['ips'][] = $_SERVER['REMOTE_ADDR'];
}
}

Řízení přístupu na základě rolí:

<?php
class XOOPSUser {
public function hasPermission(string $permissionName): bool
{
// Get user groups
$groups = $this->getGroups();
// Check if any group has permission
foreach ($groups as $groupId) {
if ($this->checkGroupPermission($groupId, $permissionName)) {
return true;
}
}
return false;
}
/**
* User groups and their permissions
* Admin: Full access
* Moderator: Content management
* User: Create own content
* Guest: Read-only access
*/
private function checkGroupPermission(int $groupId, string $permission): bool
{
$permissions = [
1 => ['admin_access'], // Admin group
2 => ['moderate_content', 'edit_own'], // Moderator group
3 => ['create_content', 'edit_own'], // User group
4 => [], // Guest group (no permissions)
];
return in_array($permission, $permissions[$groupId] ?? []);
}
}

Zabraňte chybám vstřikování a typu SQL:

<?php
// Always use prepared statements
$sql = 'SELECT * FROM users WHERE id = ?';
$result = $db->query($sql, [$userId]); // ✅ Safe
// Input validation
function 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),
];
}
// XOOPS Safe Input class
$safe = \XMF\Request::getHtmlRequest('var_name', '');
$int = \XMF\Request::getInt('page', 1);

Zabraňte útokům XSS:

<?php
// In PHP templates
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// In Smarty templates (automatic escaping)
<{$user_input}> {* Escaped by default *}
<{$html|escape:false}> {* Only when needed *}
// JavaScript context
<script>
var message = "<{$userMessage|escape:'javascript'}>";
</script>
// URL context
<a href="<{$url|escape:'url'}>">Link</a>

Zabránění padělání žádostí napříč weby:

<?php
// Generate CSRF token
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// In forms
<form method="POST">
<input type="hidden" name="csrf_token" value="<{$csrf_token}>">
<button type="submit">Submit</button>
</form>
// Validate token
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
// Process form
} else {
throw new InvalidTokenException('CSRF token invalid');
}
}

  1. Komplexní ochrana – Pokrývá hlavní třídy zranitelnosti
  2. Vrstvené zabezpečení – Více vrstev obrany
  3. Flexibilní RBAC – Jemná kontrola oprávnění
  4. Audit Trail – Sledujte bezpečnostní události
  5. Odvětvový standard – V souladu s doporučeními OWASP
  6. Integrace modulů – Moduly snadno používají bezpečnostní API
  1. Složitost – Je potřeba více kódu a konfigurace
  2. Výkon – Hašování a ověřování zvyšují režii
  3. Uživatelská zkušenost – Zabezpečení někdy nepohodlné
  4. Údržba – Vyžaduje průběžné aktualizace zabezpečení
  5. Vyžadováno školení – Vývojáři musí dodržovat postupy
RizikoZávažnostZmírnění
Vývojář ignoruje zabezpečeníVysokáKontrola kódu, bezpečnostní školení
Objevená nová zranitelnostStředníPravidelné bezpečnostní audity, aktualizace
Dopad na výkonNízkáOptimalizujte horké cesty, ukládání do mezipaměti
Příliš složitá oprávněníStředníPřehledná dokumentace, příklady

Nejlepší bezpečnostní postupy

Sekce “Nejlepší bezpečnostní postupy”
<?php
// ✅ DO: Use prepared statements
$result = $db->prepare('SELECT * FROM table WHERE id = ?')->execute([$id]);
// ❌ DON'T: Concatenate queries
$result = $db->query("SELECT * FROM table WHERE id = $id");
// ✅ DO: Escape output
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
// ❌ DON'T: Output raw user data
echo $user_input;
// ✅ DO: Check permissions
if (!$user->hasPermission('edit_content')) {
throw new PermissionException();
}
// ❌ DON'T: Trust user roles directly
if ($_POST['is_admin']) {
// Make user admin - SECURITY HOLE!
}
// ✅ DO: Validate input types
$page = (int)$_GET['page'];
// ❌ DON'T: Use untrusted values directly
$sql .= " LIMIT " . $_GET['limit'];

Proč nezvolit hned na začátku: Příliš složité pro prostředí sdíleného hostování, ale dobré pro budoucí integraci s externími systémy ověřování.

Dvoufaktorová autentizace (2FA)

Sekce “Dvoufaktorová autentizace (2FA)”

Stav: Přijímáno jako rozšíření, nikoli základní požadavek, viz ADR-006

Sekce “Soubory cookie relace pouze HTTP”

Stav: Implementováno – brání JavaScript v přístupu k datům relace


Související rozhodnutí

Sekce “Související rozhodnutí”
  • ADR-001: Modulární architektura - Moduly implementují zabezpečení
  • ADR-005: Systém povolení modulu
  • ADR-006: Dvoufaktorová autentizace (budoucí)

Bezpečnostní standardy

Sekce “Bezpečnostní standardy”

Kontrolní seznam implementace

Sekce “Kontrolní seznam implementace”
  • Systém ověřování uživatelů
  • Správa relací
  • Hašování hesel (bcrypt)
  • Řízení přístupu na základě rolí
  • Oprávnění modulu
  • Rámec ověřování vstupu
  • Výstup escapování (PHP + Smarty)
  • Ochrana tokenů CSRF
  • Protokolování bezpečnostního auditu
  • Omezení sazby
  • Záhlaví zabezpečení

VerzeDatumZměny
1.0.02024-01-28Počáteční dokument

#xoops #adr #zabezpečení #architektura #autentizace #autorizace #rbac