Перейти до вмісту

ADR-004 - Архітектура системи безпеки

ADR-004: Архітектура системи безпеки

Section titled “ADR-004: Архітектура системи безпеки”

Комплексна архітектура безпеки для XOOPS CMS, що захищає від сучасних загроз.


Прийнято - базовий рівень безпеки з XOOPS 2.5


XOOPS потребує надійної системи безпеки, яка:

  1. Захищає від типових веб-вразливостей (OWASP Top 10)
  2. Забезпечує детальне керування дозволами для всіх модулів
  3. Забезпечує безпечну автентифікацію користувача за сучасними стандартами
  4. Запобігає витоку даних і несанкціонованому доступу
  5. Підтримується багаторівневий контроль доступу (адміністратор, модератор, користувач, гість)
  6. Бездоганно інтегрується з усіма модулями

Сучасні веб-атаки включають:

  • SQL Injection - Зловмисний SQL у введенні користувачем
  • XSS (міжсайтовий сценарій) - вставлено JavaScript на сторінки
  • CSRF (підробка міжсайтового запиту) - Неавторизоване надсилання форм
  • Обхід автентифікації - Слабка обробка session/password
  • Обхід авторизації - Ескалація привілеїв
  • Викриття даних - конфіденційні дані в URL-адресах, журналах або кеш-пам’яті
  1. Аутентифікація користувача та керування сеансами
  2. Контроль доступу на основі ролей (RBAC)
  3. Система дозволів для модулів і об’єктів
  4. Перевірка вхідних даних і екранування вихідних даних
  5. Захист від типових атак
  6. Журнал аудиту подій безпеки
  7. Безпечна обробка паролів
  8. Захист токенів CSRF

Основна архітектура безпеки

Section titled “Основна архітектура безпеки”
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

1. Система автентифікації

Section titled “1. Система автентифікації”

Процес входу користувача:

<?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'));

Захист паролем:

<?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);
}

Безпечна обробка сеансу:

<?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'];
}
}

Контроль доступу на основі ролей:

<?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] ?? []);
}
}

4. Перевірка введених даних

Section titled “4. Перевірка введених даних”

Запобігайте ін’єкції 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);

Запобігайте атакам 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>

Запобігання підробці міжсайтових запитів:

<?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. Комплексний захист - охоплює основні класи вразливості
  2. Рівнева безпека - кілька рівнів захисту
  3. Гнучкий RBAC - детальний контроль дозволів
  4. Аудиторський слід - відстежуйте події безпеки
  5. Промисловий стандарт - відповідає рекомендаціям OWASP
  6. Інтеграція модулів - модулі легко використовують API безпеки
  1. Складність – потрібно більше коду та конфігурації
  2. Продуктивність - хешування та перевірка додають додаткових витрат
  3. Взаємодія з користувачем - Безпека іноді незручна
  4. Технічне обслуговування – потребує постійних оновлень безпеки
  5. Потрібне навчання – розробники повинні дотримуватися практики
РизикТяжкістьПом’якшення
Розробник ігнорує безпекуВисокийОгляд коду, навчання безпеки
Виявлено нові вразливостіСереднійРегулярні аудити безпеки, оновлення
Вплив на продуктивністьНизькийОптимізація гарячих шляхів, кешування
Надто складні дозволиСереднійЧітка документація, приклади

Найкращі методи безпеки

Section titled “Найкращі методи безпеки”

Для розробників модулів

Section titled “Для розробників модулів”
<?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'];

Розглянуті альтернативи

Section titled “Розглянуті альтернативи”

Чому не вибрано спочатку: Занадто складний для спільного хостингового середовища, але хороший для майбутньої інтеграції із зовнішніми системами авторизації.

Двофакторна автентифікація (2FA)

Section titled “Двофакторна автентифікація (2FA)”

Статус: Прийнято як розширення, а не як основну вимогу, див. ADR-006

Section titled “Сеансові файли cookie лише HTTP”

Статус: Реалізовано - забороняє доступ JavaScript до даних сеансу


  • ADR-001: Модульна архітектура - Модулі забезпечують безпеку
  • ADR-005: Система дозволів модуля
  • ADR-006: двофакторна автентифікація (майбутнє)

  • OWASP ZAP - Тестування безпеки
  • Snyk - Сканування вразливостей
  • SonarQube - Якість коду

Контрольний список впровадження

Section titled “Контрольний список впровадження”
  • Система аутентифікації користувачів
  • Керування сеансами
  • Хешування пароля (bcrypt)
  • Контроль доступу на основі ролей
  • Дозволи модуля
  • Структура перевірки вхідних даних
  • Екранування виводу (PHP + Smarty)
  • Захист токенів CSRF
  • Журнал аудиту безпеки
  • Обмеження швидкості
  • Заголовки безпеки

ВерсіяДатаЗміни
1.0.02024-01-28Вихідний документ

#xoops #adr #security #architecture #authentication #authorization #rbac