חיטוי קלט
לעולם אל תסמוך על קלט משתמש. אמת וחיטוי תמיד את כל נתוני הקלט לפני השימוש בהם. XOOPS מספקת את המחלקה MyTextSanitizer לניקוי קלט טקסט ופונקציות עוזר שונות לאימות.
תיעוד קשור
Section titled “תיעוד קשור”- אבטחה-שיטות עבודה מומלצות - מדריך אבטחה מקיף
- CSRF-Protection - מערכת אסימונים ומחלקת XoopsSecurity
- SQL-הזרקה-מניעת - נוהלי אבטחת מסדי נתונים
כלל הזהב
Section titled “כלל הזהב”לעולם אל תסמוך על קלט משתמש. כל הנתונים ממקורות חיצוניים חייבים להיות:
- מאומת: בדוק שהוא תואם את הפורמט והסוג הצפויים
- מחטא: הסר או בריחה דמויות שעלולות להיות מסוכנות
- Escape: בעת הפלט, escape עבור ההקשר הספציפי (HTML, JavaScript, SQL)
MyTextSnitizer Class
Section titled “MyTextSnitizer Class”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 'עיבוד תוכן של Textarea
Section titled “עיבוד תוכן של Textarea”שיטת 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();}אימות URLs
Section titled “אימות URLs”$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() לאימות פורמט ספציפי
- השתמש בהטלת סוג עבור ערכים מספריים
- רשימה הלבנה של ערכים מותרים עבור כניסות נבחרות
- אמת לפני חיטוי
- בריחה בפלט, לא בקלט
- השתמש בהצהרות מוכנות עבור שאילתות מסד נתונים
- צור מחלקות אימות לטפסים מורכבים
- לעולם אל תבטח באימות בצד הלקוח - אמת תמיד בצד השרת
#אבטחה #חיטוי #validation #xoops #MyTextSanitizer #טיפול בקלט