-- migration_security_hardening.sql -- -- Migration de durcissement securite suite a l'audit du 20/09/2026, -- POUR UNE BASE DEJA EN PRODUCTION (schema anterieur a la fusion en -- install_full_schema.sql). Si vous demarrez une installation NEUVE, -- n'utilisez PAS ce fichier : utilisez install_full_schema.sql qui -- inclut deja tout ce qui suit. -- -- Contenu : -- 1. Table login_attempts pour un rate limiting stocke en base, -- independant de la session PHP du visiteur (donc non -- contournable en vidant les cookies ou en ouvrant une navigation -- privee). Utilisee par admin/admin_auth.php et admin/login.php. -- 2. Ajout de la valeur 'cellmapper_import' a l'ENUM `source` de -- staging_cells : admin/cellmapper_import.php insere des lignes -- avec source = "cellmapper_import", ce qui echoue (ou tronque -- silencieusement selon le mode strict SQL) si l'ENUM d'origine ne -- contient que ('ntm_import','manual_form'). Sans ce correctif, -- tout import CellMapper sur une base anterieure a la fusion du -- schema echoue en base malgre un code PHP fonctionnel. -- -- Les roles admin_users (admin/reviewer) sont volontairement REPORTES -- a une migration future : tant qu'un seul compte administrateur est -- utilise, ajouter une colonne role non appliquee partout donnerait -- une fausse impression de securite sans reel controle d'acces. -- -- A executer une seule fois sur la base existante : -- mysql --defaults-extra-file=/etc/netmonster/.my.cnf netmonster < migration_security_hardening.sql -- --------------------------------------------------------------------- -- 1. Rate limiting de connexion -- --------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS login_attempts ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, username_normalized VARCHAR(190) NOT NULL, ip_address VARCHAR(45) NOT NULL, attempted_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, success TINYINT(1) NOT NULL DEFAULT 0, turnstile_verified TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY (id), KEY idx_username_ip_time (username_normalized, ip_address, attempted_at), KEY idx_ip_time (ip_address, attempted_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- Purge recommandee via cron (pas dans cette migration), pour eviter -- que la table ne grossisse indefiniment : -- DELETE FROM login_attempts WHERE attempted_at < NOW() - INTERVAL 30 DAY; -- --------------------------------------------------------------------- -- 2. Ajout de 'cellmapper_import' a l'ENUM source de staging_cells -- -- MODIFY COLUMN reconstruit l'ENUM avec la valeur supplementaire, sans -- toucher aux lignes existantes (leurs valeurs actuelles 'ntm_import' -- et 'manual_form' restent valides et inchangees dans le nouvel ENUM). -- Operation instantanee ou quasi-instantanee selon la version -- MySQL/MariaDB (pas de reecriture de table necessaire pour un ajout -- de valeur en fin d'ENUM sur les versions recentes). -- --------------------------------------------------------------------- ALTER TABLE staging_cells MODIFY COLUMN source ENUM('ntm_import','manual_form','cellmapper_import') NOT NULL DEFAULT 'ntm_import';