diff --git a/includes/config.php b/includes/config.php index 5cd44f6..9e4a6a9 100644 --- a/includes/config.php +++ b/includes/config.php @@ -1,5 +1,8 @@ = 300) { + error_log('PeerTube API HTTP error: ' . $httpCode); return []; } @@ -116,6 +146,85 @@ function callPeerTubeApi($endpoint, $params = []) { return $data ?: []; } +/** + * Valide l'URL PeerTube pour prévenir les attaques SSRF + * + * @param string $url URL à valider + * @return bool True si l'URL est valide et sûre + */ +function isValidPeerTubeUrl($url) { + // Vérifier que l'URL est bien formée + $parsed = parse_url($url); + if (!$parsed || !isset($parsed['scheme']) || !isset($parsed['host'])) { + return false; + } + + // Autoriser uniquement HTTPS (ou HTTP en développement) + if (!in_array($parsed['scheme'], ['https', 'http'])) { + return false; + } + + // Bloquer les adresses IP privées et locales + $host = $parsed['host']; + if (filter_var($host, FILTER_VALIDATE_IP)) { + if (!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { + return false; + } + } + + // Bloquer localhost et autres domaines dangereux + $blockedHosts = ['localhost', '127.0.0.1', '::1', '0.0.0.0', 'metadata.google.internal']; + if (in_array(strtolower($host), $blockedHosts)) { + return false; + } + + return true; +} + +/** + * Valide l'endpoint API pour prévenir l'injection de chemins + * + * @param string $endpoint Endpoint à valider + * @return bool True si l'endpoint est valide + */ +function isValidApiEndpoint($endpoint) { + // Bloquer les tentatives de path traversal + if (strpos($endpoint, '..') !== false || strpos($endpoint, '//') !== false) { + return false; + } + + // Autoriser uniquement les caractères alphanumériques, tirets, underscores et slashes + if (!preg_match('/^[a-zA-Z0-9\/_-]+$/', $endpoint)) { + return false; + } + + // Liste blanche des endpoints autorisés + $allowedEndpoints = [ + 'videos', + 'videos/categories', + 'search/videos', + 'videos/.*', // Pour les endpoints dynamiques comme videos/{id} + 'videos/.*/comment-threads', // Pour les commentaires + 'accounts', + 'accounts/.*/videos' // Pour les vidéos d'un compte spécifique + ]; + + foreach ($allowedEndpoints as $pattern) { + // Remplacer les .* par des marqueurs temporaires + $tempPattern = str_replace('.*', '__WILDCARD__', $pattern); + // Échapper les caractères spéciaux regex + $escapedPattern = preg_quote($tempPattern, '/'); + // Remettre les wildcards en place + $regexPattern = str_replace('__WILDCARD__', '.*', $escapedPattern); + + if (preg_match('/^' . $regexPattern . '$/', $endpoint)) { + return true; + } + } + + return false; +} + /** * Récupère les catégories depuis l'API PeerTube *