แนวทางการรักษาความปลอดภัย
เอกสารนี้สรุปแนวทางปฏิบัติที่ดีที่สุดด้านความปลอดภัยสำหรับการพัฒนา XOOPS ซึ่งครอบคลุมการตรวจสอบอินพุต การเข้ารหัสเอาต์พุต การตรวจสอบสิทธิ์ การอนุญาต และการป้องกันช่องโหว่บนเว็บทั่วไป
หลักการรักษาความปลอดภัย
หัวข้อที่มีชื่อว่า “หลักการรักษาความปลอดภัย”mermaidflowchart TB subgraph "Defense in Depth" A[Input Validation] --> B[Authentication] B --> C[Authorization] C --> D[Data Sanitization] D --> E[Output Encoding] E --> F[Audit Logging] endการตรวจสอบอินพุต
หัวข้อที่มีชื่อว่า “การตรวจสอบอินพุต”ขอฆ่าเชื้อ
หัวข้อที่มีชื่อว่า “ขอฆ่าเชื้อ”use Xoops\Core\Request;
// Always use typed getters$id = Request::getInt('id', 0, 'GET');$name = Request::getString('name', '', 'POST');$email = Request::getEmail('email', '', 'POST');$url = Request::getUrl('website', '', 'POST');
// Never use raw $_GET/$_POST/$_REQUEST// Bad: $id = $_GET['id'];// Good: $id = Request::getInt('id', 0, 'GET');กฎการตรวจสอบ
หัวข้อที่มีชื่อว่า “กฎการตรวจสอบ”// Validate before useif ($id <= 0) { throw new InvalidArgumentException('Invalid ID');}
if (!preg_match('/^[a-zA-Z0-9_]{3,50}$/', $username)) { throw new InvalidArgumentException('Invalid username format');}
// Use whitelist validation for enums$allowedStatuses = ['draft', 'published', 'archived'];if (!in_array($status, $allowedStatuses, true)) { throw new InvalidArgumentException('Invalid status');}SQL การป้องกันการฉีด
หัวข้อที่มีชื่อว่า “SQL การป้องกันการฉีด”ใช้แบบสอบถามแบบกำหนดพารามิเตอร์
หัวข้อที่มีชื่อว่า “ใช้แบบสอบถามแบบกำหนดพารามิเตอร์”// GOOD: Parameterized query$sql = "SELECT * FROM {$xoopsDB->prefix('users')} WHERE uid = ?";$result = $xoopsDB->query($sql, [$userId]);
// BAD: String concatenation (vulnerable!)// $sql = "SELECT * FROM users WHERE uid = " . $userId;การใช้ออบเจ็กต์เกณฑ์
หัวข้อที่มีชื่อว่า “การใช้ออบเจ็กต์เกณฑ์”use Criteria;use CriteriaCompo;
$criteria = new CriteriaCompo();$criteria->add(new Criteria('status', 'published'));$criteria->add(new Criteria('uid', $userId, '='));$criteria->add(new Criteria('created', time() - 86400, '>'));
$articles = $articleHandler->getObjects($criteria);XSS การป้องกัน
หัวข้อที่มีชื่อว่า “XSS การป้องกัน”การเข้ารหัสเอาต์พุต
หัวข้อที่มีชื่อว่า “การเข้ารหัสเอาต์พุต”use Xoops\Core\Text\Sanitizer;
// HTML context$safeName = htmlspecialchars($userName, ENT_QUOTES, 'UTF-8');
// In templates (auto-escaped){$userName|escape}
// For rich content$sanitizer = Sanitizer::getInstance();$safeContent = $sanitizer->sanitizeForDisplay($content);นโยบายการรักษาความปลอดภัยของเนื้อหา
หัวข้อที่มีชื่อว่า “นโยบายการรักษาความปลอดภัยของเนื้อหา”// Set CSP headersheader("Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'");CSRF การป้องกัน
หัวข้อที่มีชื่อว่า “CSRF การป้องกัน”การใช้งานโทเค็น
หัวข้อที่มีชื่อว่า “การใช้งานโทเค็น”// Generate tokenuse Xoops\Core\Security;
$token = Security::createToken();
// In formecho '<input type="hidden" name="XOOPS_TOKEN_REQUEST" value="' . $token . '">';
// Verify on submissionif (!Security::checkToken()) { die('Security token mismatch');}การใช้ XoopsForm
หัวข้อที่มีชื่อว่า “การใช้ XoopsForm”// Automatically adds CSRF token$form = new XoopsThemeForm('Edit Article', 'articleform', 'save.php');$form->addElement(new XoopsFormHiddenToken());การรับรองความถูกต้อง
หัวข้อที่มีชื่อว่า “การรับรองความถูกต้อง”การจัดการรหัสผ่าน
หัวข้อที่มีชื่อว่า “การจัดการรหัสผ่าน”// Hash passwords (PHP 5.5+)$hashedPassword = password_hash($plainPassword, PASSWORD_ARGON2ID);
// Verify passwordsif (password_verify($plainPassword, $storedHash)) { // Password correct}
// Check if rehash neededif (password_needs_rehash($storedHash, PASSWORD_ARGON2ID)) { $newHash = password_hash($plainPassword, PASSWORD_ARGON2ID); // Update stored hash}ความปลอดภัยของเซสชัน
หัวข้อที่มีชื่อว่า “ความปลอดภัยของเซสชัน”// Regenerate session ID after loginsession_regenerate_id(true);
// Set secure session cookie optionsini_set('session.cookie_httponly', 1);ini_set('session.cookie_secure', 1);ini_set('session.cookie_samesite', 'Lax');การอนุญาต
หัวข้อที่มีชื่อว่า “การอนุญาต”การตรวจสอบสิทธิ์
หัวข้อที่มีชื่อว่า “การตรวจสอบสิทธิ์”// Check module adminif (!$xoopsUser || !$xoopsUser->isAdmin($xoopsModule->mid())) { redirect_header('index.php', 3, 'Access denied');}
// Check group permissions$grouppermHandler = xoops_getHandler('groupperm');$groups = $xoopsUser ? $xoopsUser->getGroups() : [XOOPS_GROUP_ANONYMOUS];
if (!$grouppermHandler->checkRight('view_item', $itemId, $groups, $moduleId)) { throw new AccessDeniedException('Permission denied');}การเข้าถึงตามบทบาท
หัวข้อที่มีชื่อว่า “การเข้าถึงตามบทบาท”class PermissionChecker{ public function canEdit(Article $article, ?XoopsUser $user): bool { if (!$user) { return false; }
// Admin can edit anything if ($user->isAdmin()) { return true; }
// Author can edit their own if ($article->getAuthorId() === $user->uid()) { return true; }
// Check editor permission return $this->hasPermission($user, 'article_edit'); }}ความปลอดภัยในการอัพโหลดไฟล์
หัวข้อที่มีชื่อว่า “ความปลอดภัยในการอัพโหลดไฟล์”class SecureUploader{ private array $allowedMimeTypes = [ 'image/jpeg', 'image/png', 'image/gif' ];
private array $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
public function validate(array $file): bool { // Check file size if ($file['size'] > 2 * 1024 * 1024) { throw new FileTooLargeException(); }
// Verify MIME type $finfo = new finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->file($file['tmp_name']);
if (!in_array($mimeType, $this->allowedMimeTypes, true)) { throw new InvalidFileTypeException(); }
// Check extension $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (!in_array($extension, $this->allowedExtensions, true)) { throw new InvalidFileTypeException(); }
// Generate safe filename return true; }
public function generateSafeFilename(string $original): string { $extension = strtolower(pathinfo($original, PATHINFO_EXTENSION)); return bin2hex(random_bytes(16)) . '.' . $extension; }}การบันทึกการตรวจสอบ
หัวข้อที่มีชื่อว่า “การบันทึกการตรวจสอบ”class SecurityLogger{ public function logAuthAttempt(string $username, bool $success, string $ip): void { $data = [ 'username' => $username, 'success' => $success, 'ip' => $ip, 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'timestamp' => time() ];
// Log to database or file $this->log('auth', $data); }
public function logSensitiveAction(int $userId, string $action, array $context): void { $data = [ 'user_id' => $userId, 'action' => $action, 'context' => json_encode($context), 'ip' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time() ];
$this->log('audit', $data); }}ส่วนหัวการรักษาความปลอดภัย
หัวข้อที่มีชื่อว่า “ส่วนหัวการรักษาความปลอดภัย”// Recommended security headersheader('X-Content-Type-Options: nosniff');header('X-Frame-Options: SAMEORIGIN');header('X-XSS-Protection: 1; mode=block');header('Referrer-Policy: strict-origin-when-cross-origin');header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
// HSTS (only for HTTPS sites)if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { header('Strict-Transport-Security: max-age=31536000; includeSubDomains');}การจำกัดอัตรา
หัวข้อที่มีชื่อว่า “การจำกัดอัตรา”class RateLimiter{ public function check(string $key, int $maxAttempts, int $windowSeconds): bool { $cacheKey = 'rate_limit:' . $key; $attempts = (int) $this->cache->get($cacheKey, 0);
if ($attempts >= $maxAttempts) { return false; // Rate limited }
$this->cache->increment($cacheKey, 1, $windowSeconds); return true; }}
// Usage$limiter = new RateLimiter();if (!$limiter->check('login:' . $ip, 5, 300)) { throw new TooManyRequestsException('Too many login attempts');}รายการตรวจสอบความปลอดภัย
หัวข้อที่มีชื่อว่า “รายการตรวจสอบความปลอดภัย”- อินพุตของผู้ใช้ทั้งหมดได้รับการตรวจสอบและฆ่าเชื้อแล้ว
- แบบสอบถามที่กำหนดพารามิเตอร์สำหรับการดำเนินการฐานข้อมูลทั้งหมด
- การเข้ารหัสเอาต์พุตสำหรับเนื้อหาที่ผู้ใช้สร้างขึ้นทั้งหมด
- CSRF โทเค็นในทุกรูปแบบที่เปลี่ยนแปลงสถานะ
- การแฮชรหัสผ่านที่ปลอดภัย (Argon2id)
- กำหนดค่าความปลอดภัยของเซสชันแล้ว
- การตรวจสอบการอัพโหลดไฟล์
- ตั้งค่าส่วนหัวความปลอดภัยแล้ว
- มีการใช้การจำกัดอัตราแล้ว
- เปิดใช้งานการบันทึกการตรวจสอบแล้ว
- ข้อความแสดงข้อผิดพลาดไม่รั่วไหลข้อมูลที่ละเอียดอ่อน
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- ระบบยืนยันตัวตน
- ระบบการอนุญาต
- การตรวจสอบอินพุต