Дезінфекція входу
Ніколи не довіряйте введеним користувачами. Завжди перевіряйте та дезінфікуйте всі введені дані перед їх використанням. XOOPS надає клас MyTextSanitizer для очищення введення тексту та різноманітні допоміжні функції для перевірки.
Пов’язана документація
Section titled “Пов’язана документація”- Security-Best-Practices - Вичерпний посібник із безпеки
- CSRF-Protection - система токенів і клас XoopsSecurity
- SQL-Injection-Prevention - Методи безпеки бази даних
Золоте правило
Section titled “Золоте правило”Ніколи не довіряйте введеним користувачами. Усі дані із зовнішніх джерел мають бути:
- Перевірено: перевірте, чи відповідає очікуваний формат і тип
- Очистити: видаліть потенційно небезпечних персонажів або втечі від них
- Escaped: під час виведення екрануйте для певного контексту (HTML, JavaScript, SQL)
Клас MyTextSanitizer
Section titled “Клас MyTextSanitizer”XOOPS надає клас MyTextSanitizer (зазвичай відомий як $myts) для очищення тексту.
Отримання екземпляра
Section titled “Отримання екземпляра”// Get the singleton instance$myts = MyTextSanitizer::getInstance();Очищення основного тексту
Section titled “Очищення основного тексту”$myts = MyTextSanitizer::getInstance();
// For plain text fields (no HTML allowed)$title = $myts->htmlSpecialChars($_POST['title']);
// This converts:// < to <// > to >// & to &// " to "// ' to 'Обробка вмісту текстового поля
Section titled “Обробка вмісту текстового поля”Метод displayTarea() забезпечує комплексну обробку текстової області:
$myts = MyTextSanitizer::getInstance();
$content = $myts->displayTarea( $_POST['content'], $allowhtml = 0, // 0 = No HTML allowed, 1 = HTML allowed $allowsmiley = 1, // 1 = Smilies enabled $allowxcode = 1, // 1 = XOOPS codes enabled (BBCode) $allowimages = 1, // 1 = Images allowed $allowlinebreak = 1 // 1 = Line breaks converted to <br>);Загальні методи дезінфекції
Section titled “Загальні методи дезінфекції”$myts = MyTextSanitizer::getInstance();
// HTML special characters escaping$safe_text = $myts->htmlSpecialChars($text);
// Strip slashes if magic quotes are on$text = $myts->stripSlashesGPC($text);
// Convert XOOPS codes (BBCode) to HTML$html = $myts->xoopsCodeDecode($text);
// Convert smileys to images$html = $myts->smiley($text);
// Make clickable links$html = $myts->makeClickable($text);
// Complete text processing for preview$preview = $myts->previewTarea($text, $allowhtml, $allowsmiley, $allowxcode);Перевірка введених даних
Section titled “Перевірка введених даних”Перевірка цілих значень
Section titled “Перевірка цілих значень”// Validate integer ID$id = isset($_REQUEST['id']) ? (int)$_REQUEST['id'] : 0;
if ($id <= 0) { redirect_header('index.php', 3, 'Invalid ID'); exit();}
// Alternative with filter_var$id = filter_var($_REQUEST['id'] ?? 0, FILTER_VALIDATE_INT);if ($id === false || $id <= 0) { redirect_header('index.php', 3, 'Invalid ID'); exit();}Перевірка адрес електронної пошти
Section titled “Перевірка адрес електронної пошти”$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if (!$email) { redirect_header('form.php', 3, 'Invalid email address'); exit();}Перевірка URL-адрес
Section titled “Перевірка URL-адрес”$url = filter_var($_POST['url'], FILTER_VALIDATE_URL);
if (!$url) { redirect_header('form.php', 3, 'Invalid URL'); exit();}
// Additional check for allowed protocols$parsed = parse_url($url);$allowed_schemes = ['http', 'https'];if (!in_array($parsed['scheme'], $allowed_schemes)) { redirect_header('form.php', 3, 'Only HTTP and HTTPS URLs are allowed'); exit();}Перевірка дат
Section titled “Перевірка дат”$date = $_POST['date'] ?? '';
// Validate date format (YYYY-MM-DD)if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { redirect_header('form.php', 3, 'Invalid date format'); exit();}
// Validate actual date validity$parts = explode('-', $date);if (!checkdate($parts[1], $parts[2], $parts[0])) { redirect_header('form.php', 3, 'Invalid date'); exit();}Перевірка імен файлів
Section titled “Перевірка імен файлів”// Remove all characters except alphanumeric, underscore, and hyphen$filename = preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['filename']);
// Or use a whitelist approach$allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-';$filename = '';foreach (str_split($_POST['filename']) as $char) { if (strpos($allowed_chars, $char) !== false) { $filename .= $char; }}Обробка різних типів введення
Section titled “Обробка різних типів введення”Введення рядка
Section titled “Введення рядка”$myts = MyTextSanitizer::getInstance();
// Short text (titles, names)$title = $myts->htmlSpecialChars(trim($_POST['title']));
// Limit lengthif (strlen($title) > 255) { $title = substr($title, 0, 255);}
// Check for empty required fieldsif (empty($title)) { redirect_header('form.php', 3, 'Title is required'); exit();}Числове введення
Section titled “Числове введення”// Integer$count = (int)$_POST['count'];$count = max(0, min($count, 1000)); // Ensure range 0-1000
// Float$price = (float)$_POST['price'];$price = round($price, 2); // Round to 2 decimal places
// Validate rangeif ($price < 0 || $price > 99999.99) { redirect_header('form.php', 3, 'Invalid price'); exit();}Логічний вхід
Section titled “Логічний вхід”// Checkbox values$is_active = isset($_POST['is_active']) ? 1 : 0;
// Or with explicit value check$is_active = ($_POST['is_active'] ?? '') === '1' ? 1 : 0;Введення масиву
Section titled “Введення масиву”// Validate array input (e.g., multiple checkboxes)$selected_ids = [];if (isset($_POST['ids']) && is_array($_POST['ids'])) { foreach ($_POST['ids'] as $id) { $clean_id = (int)$id; if ($clean_id > 0) { $selected_ids[] = $clean_id; } }}Select/Option Вхід
Section titled “Select/Option Вхід”// Validate against allowed values$allowed_statuses = ['draft', 'published', 'archived'];$status = $_POST['status'] ?? '';
if (!in_array($status, $allowed_statuses)) { redirect_header('form.php', 3, 'Invalid status'); exit();}Об’єкт запиту (XMF)
Section titled “Об’єкт запиту (XMF)”У разі використання XMF клас Request забезпечує чистішу обробку введення:
use Xmf\Request;
// Get integer$id = Request::getInt('id', 0);
// Get string$title = Request::getString('title', '');
// Get array$ids = Request::getArray('ids', []);
// Get with method specification$id = Request::getInt('id', 0, 'POST');$search = Request::getString('q', '', 'GET');
// Check request methodif (Request::getMethod() !== 'POST') { redirect_header('form.php', 3, 'Invalid request method'); exit();}Створення класу перевірки
Section titled “Створення класу перевірки”Для складних форм створіть окремий клас перевірки:
<?phpnamespace XoopsModules\MyModule;
class Validator{ private $errors = [];
public function validateItem(array $data): bool { $this->errors = [];
// Title validation if (empty($data['title'])) { $this->errors['title'] = 'Title is required'; } elseif (strlen($data['title']) > 255) { $this->errors['title'] = 'Title must be 255 characters or less'; }
// Email validation if (!empty($data['email'])) { if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { $this->errors['email'] = 'Invalid email format'; } }
// Status validation $allowed = ['draft', 'published']; if (!in_array($data['status'], $allowed)) { $this->errors['status'] = 'Invalid status'; }
return empty($this->errors); }
public function getErrors(): array { return $this->errors; }
public function getError(string $field): ?string { return $this->errors[$field] ?? null; }}Використання:
$validator = new Validator();$data = [ 'title' => $_POST['title'], 'email' => $_POST['email'], 'status' => $_POST['status'],];
if (!$validator->validateItem($data)) { $errors = $validator->getErrors(); // Display errors to user}Очищення для зберігання бази даних
Section titled “Очищення для зберігання бази даних”Під час зберігання даних у базі даних:
$myts = MyTextSanitizer::getInstance();
// For storage (will be processed again on display)$title = $myts->addSlashes($_POST['title']);
// Better: Use prepared statements (see SQL Injection Prevention)$sql = "INSERT INTO " . $xoopsDB->prefix('mytable') . " (title) VALUES (?)";$result = $xoopsDB->query($sql, [$_POST['title']]);Дезінфекція дисплея
Section titled “Дезінфекція дисплея”Різні контексти вимагають різного екранування:
$myts = MyTextSanitizer::getInstance();
// HTML contextecho $myts->htmlSpecialChars($title);
// Within HTML attributesecho htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
// JavaScript contextecho json_encode($title);
// URL parameterecho urlencode($title);
// Full URLecho htmlspecialchars($url, ENT_QUOTES, 'UTF-8');Поширені підводні камені
Section titled “Поширені підводні камені”Подвійне кодування
Section titled “Подвійне кодування”Проблема: дані кодуються кілька разів
// Wrong - double encoding$title = $myts->htmlSpecialChars($myts->htmlSpecialChars($_POST['title']));
// Right - encode once, at the appropriate time$title = $_POST['title']; // Store rawecho $myts->htmlSpecialChars($title); // Encode on outputНевідповідне кодування
Section titled “Невідповідне кодування”Проблема: деякі виходи закодовані, а деякі ні
Рішення: завжди використовуйте послідовний підхід, бажано кодування на виході:
// Template assignment$GLOBALS['xoopsTpl']->assign('title', htmlspecialchars($title, ENT_QUOTES, 'UTF-8'));Відсутня перевірка
Section titled “Відсутня перевірка”Проблема: лише дезінфекція без перевірки
Рішення: завжди спочатку перевіряйте, а потім дезінфікуйте:
// First validateif (!preg_match('/^[a-z0-9_]+$/', $_POST['username'])) { redirect_header('form.php', 3, 'Username contains invalid characters'); exit();}
// Then sanitize for storage/display$username = $myts->htmlSpecialChars($_POST['username']);Підсумок найкращих практик
Section titled “Підсумок найкращих практик”- Використовуйте MyTextSanitizer для обробки текстового вмісту
- Використовуйте filter_var() для перевірки певного формату
- Використовуйте приведення типу для числових значень
- Дозволені значення білого списку для вибраних вхідних даних
- Перевірте перед дезобробкою
- Вихід при виведенні, а не при введенні
- Використовуйте підготовлені оператори для запитів до бази даних
- Створіть класи перевірки для складних форм
- Ніколи не довіряйте перевірці на стороні клієнта – завжди перевіряйте на стороні сервера
#security #sanitization #validation #xoops #MyTextSanitizer #input-handling