Best practice di sicurezza
2.5.x ✅ 4.0.x ✅
Questo documento fornisce le migliori pratiche di sicurezza completa per gli sviluppatori di moduli XOOPS. Seguire queste linee guida aiuterà a garantire che i tuoi moduli siano sicuri e non introducano vulnerabilità nelle installazioni di XOOPS.
Principi di sicurezza
Sezione intitolata “Principi di sicurezza”Ogni sviluppatore XOOPS dovrebbe seguire questi principi di sicurezza fondamentali:
- Defense in Depth: Implementa più livelli di controlli di sicurezza
- Least Privilege: Fornisci solo i diritti di accesso minimi necessari
- Input Validation: Non fidarti mai dell’input dell’utente
- Secure by Default: La sicurezza dovrebbe essere la configurazione predefinita
- Keep It Simple: I sistemi complessi sono più difficili da proteggere
Documentazione correlata
Sezione intitolata “Documentazione correlata”- CSRF-Protection - Sistema di token e classe XoopsSecurity
- Input-Sanitization - MyTextSanitizer e validazione
- SQL-Injection-Prevention - Pratiche di sicurezza del database
Elenco di controllo di riferimento rapido
Sezione intitolata “Elenco di controllo di riferimento rapido”Prima di rilasciare il tuo modulo, verifica:
- Tutti i moduli includono token XOOPS
- Tutti gli input dell’utente sono validati e sanificati
- Tutti gli output sono correttamente escapati
- Tutte le query del database utilizzano istruzioni parametrizzate
- I caricamenti di file sono correttamente validati
- I controlli di autenticazione e autorizzazione sono in atto
- La gestione degli errori non rivela informazioni sensibili
- La configurazione sensibile è protetta
- Le librerie di terze parti sono aggiornate
- I test di sicurezza sono stati eseguiti
Autenticazione e autorizzazione
Sezione intitolata “Autenticazione e autorizzazione”Controllo dell’autenticazione dell’utente
Sezione intitolata “Controllo dell’autenticazione dell’utente”// Verifica se l'utente è loggatoif (!is_object($GLOBALS['xoopsUser'])) { redirect_header(XOOPS_URL, 3, _NOPERM); exit();}Controllo dei permessi dell’utente
Sezione intitolata “Controllo dei permessi dell’utente”// Verifica se l'utente ha il permesso di accedere a questo moduloif (!$GLOBALS['xoopsUser']->isAdmin($xoopsModule->mid())) { redirect_header(XOOPS_URL, 3, _NOPERM); exit();}
// Verifica permesso specifico$moduleHandler = xoops_getHandler('module');$module = $moduleHandler->getByDirname('mymodule');$moduleperm_handler = xoops_getHandler('groupperm');$groups = $GLOBALS['xoopsUser']->getGroups();
if (!$moduleperm_handler->checkRight('mymodule_view', $item_id, $groups, $module->getVar('mid'))) { redirect_header(XOOPS_URL, 3, _NOPERM); exit();}Impostazione dei permessi dei moduli
Sezione intitolata “Impostazione dei permessi dei moduli”// Crea permesso nella funzione di installazione/aggiornamento$gpermHandler = xoops_getHandler('groupperm');$gpermHandler->deleteByModule($module->getVar('mid'), 'mymodule_view');
// Aggiungi permesso per tutti i gruppi$groups = [XOOPS_GROUP_ADMIN, XOOPS_GROUP_USERS, XOOPS_GROUP_ANONYMOUS];foreach ($groups as $group_id) { $gpermHandler->addRight('mymodule_view', 1, $group_id, $module->getVar('mid'));}Sicurezza della sessione
Sezione intitolata “Sicurezza della sessione”Best practice per la gestione della sessione
Sezione intitolata “Best practice per la gestione della sessione”- Non memorizzare informazioni sensibili nella sessione
- Rigenerare gli ID sessione dopo il login/cambiamenti di privilegi
- Validare i dati della sessione prima di usarli
// Regenerate session ID after loginsession_regenerate_id(true);
// Validate session dataif (isset($_SESSION['mymodule_user_id'])) { $user_id = (int)$_SESSION['mymodule_user_id']; // Verify user exists in database}Preventing Session Fixation
Sezione intitolata “Preventing Session Fixation”// After successful loginsession_regenerate_id(true);$_SESSION['mymodule_user_ip'] = $_SERVER['REMOTE_ADDR'];
// On subsequent requestsif ($_SESSION['mymodule_user_ip'] !== $_SERVER['REMOTE_ADDR']) { // Possible session hijacking attempt session_destroy(); redirect_header('index.php', 3, 'Session error'); exit();}File Upload Security
Sezione intitolata “File Upload Security”Validating File Uploads
Sezione intitolata “Validating File Uploads”// Check if file was uploaded properlyif (!isset($_FILES['userfile']) || $_FILES['userfile']['error'] != UPLOAD_ERR_OK) { redirect_header('index.php', 3, 'File upload error'); exit();}
// Check file sizeif ($_FILES['userfile']['size'] > 1000000) { // 1MB limit redirect_header('index.php', 3, 'File too large'); exit();}
// Check file type$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];if (!in_array($_FILES['userfile']['type'], $allowed_types)) { redirect_header('index.php', 3, 'Invalid file type'); exit();}
// Validate file extension$filename = $_FILES['userfile']['name'];$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];if (!in_array($ext, $allowed_extensions)) { redirect_header('index.php', 3, 'Invalid file extension'); exit();}Using XOOPS Uploader
Sezione intitolata “Using XOOPS Uploader”include_once XOOPS_ROOT_PATH . '/class/uploader.php';
$allowed_mimetypes = ['image/gif', 'image/jpeg', 'image/png'];$maxsize = 1000000; // 1MB$maxwidth = 1024;$maxheight = 768;$upload_dir = XOOPS_ROOT_PATH . '/uploads/mymodule';
$uploader = new XoopsMediaUploader( $upload_dir, $allowed_mimetypes, $maxsize, $maxwidth, $maxheight);
if ($uploader->fetchMedia('userfile')) { $uploader->setPrefix('mymodule_');
if ($uploader->upload()) { $filename = $uploader->getSavedFileName(); // Save filename to database } else { echo $uploader->getErrors(); }} else { echo $uploader->getErrors();}Storing Uploaded Files Securely
Sezione intitolata “Storing Uploaded Files Securely”// Define upload directory outside web root$upload_dir = XOOPS_VAR_PATH . '/uploads/mymodule';
// Create directory if it doesn't existif (!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true);}
// Move uploaded filemove_uploaded_file($_FILES['userfile']['tmp_name'], $upload_dir . '/' . $safe_filename);Error Handling and Logging
Sezione intitolata “Error Handling and Logging”Secure Error Handling
Sezione intitolata “Secure Error Handling”try { $result = someFunction(); if (!$result) { throw new Exception('Operation failed'); }} catch (Exception $e) { // Log the error xoops_error($e->getMessage());
// Display a generic error message to the user redirect_header('index.php', 3, 'An error occurred. Please try again later.'); exit();}Logging Security Events
Sezione intitolata “Logging Security Events”// Log security eventsxoops_loadLanguage('logger', 'mymodule');$GLOBALS['xoopsLogger']->addExtra('Security', 'Failed login attempt for user: ' . $username);Configuration Security
Sezione intitolata “Configuration Security”Storing Sensitive Configuration
Sezione intitolata “Storing Sensitive Configuration”// Define configuration path outside web root$config_path = XOOPS_VAR_PATH . '/configs/mymodule/config.php';
// Load configurationif (file_exists($config_path)) { include $config_path;} else { // Handle missing configuration}Protecting Configuration Files
Sezione intitolata “Protecting Configuration Files”Use .htaccess to protect configuration files:
# In .htaccess<Files "config.php"> Order Allow,Deny Deny from all</Files>Third-Party Libraries
Sezione intitolata “Third-Party Libraries”Selecting Libraries
Sezione intitolata “Selecting Libraries”- Choose actively maintained libraries
- Check for security vulnerabilities
- Verify the library’s license is compatible with XOOPS
Updating Libraries
Sezione intitolata “Updating Libraries”// Check library versionif (version_compare(LIBRARY_VERSION, '1.2.3', '<')) { xoops_error('Please update the library to version 1.2.3 or higher');}Isolating Libraries
Sezione intitolata “Isolating Libraries”// Load library in a controlled wayfunction loadLibrary($file){ $allowed = ['parser.php', 'formatter.php'];
if (!in_array($file, $allowed)) { return false; }
include_once XOOPS_ROOT_PATH . '/modules/mymodule/libraries/' . $file; return true;}Security Testing
Sezione intitolata “Security Testing”Manual Testing Checklist
Sezione intitolata “Manual Testing Checklist”- Test all forms with invalid input
- Attempt to bypass authentication and authorization
- Test file upload functionality with malicious files
- Check for XSS vulnerabilities in all output
- Test for SQL injection in all database queries
Automated Testing
Sezione intitolata “Automated Testing”Use automated tools to scan for vulnerabilities:
- Static code analysis tools
- Web application scanners
- Dependency checkers for third-party libraries
Output Escaping
Sezione intitolata “Output Escaping”HTML Context
Sezione intitolata “HTML Context”// For regular HTML contentecho htmlspecialchars($variable, ENT_QUOTES, 'UTF-8');
// Using MyTextSanitizer$myts = MyTextSanitizer::getInstance();echo $myts->htmlSpecialChars($variable);JavaScript Context
Sezione intitolata “JavaScript Context”// For data used in JavaScriptecho json_encode($variable);
// For inline JavaScriptecho 'var data = ' . json_encode($variable) . ';';URL Context
Sezione intitolata “URL Context”// For data used in URLsecho htmlspecialchars(urlencode($variable), ENT_QUOTES, 'UTF-8');Template Variables
Sezione intitolata “Template Variables”// Assign variables to Smarty template$GLOBALS['xoopsTpl']->assign('title', htmlspecialchars($title, ENT_QUOTES, 'UTF-8'));
// For HTML content that should be displayed as-is$GLOBALS['xoopsTpl']->assign('content', $myts->displayTarea($content, 1, 1, 1, 1, 1));Resources
Sezione intitolata “Resources”#security #best-practices #xoops #module-development #authentication #authorization