prepare("SELECT created_at FROM posts WHERE ip=? ORDER BY created_at DESC LIMIT 1"); $stmt->execute([$ip]); $last = $stmt->fetch(); if ($last && strtotime($last['created_at']) > time() - 60) { die("Attendez 1 minute avant de reposter!"); } $imageName = null; if (!empty($_FILES['image']['name'])) { if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) { die("Error de sauvegarde d'image"); } if ($_FILES['image']['size'] < 2 * 1024 * 1024) { die("Erreur, Image trop petite."); } /* Verify MIME type using finfo */ $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($_FILES['image']['tmp_name']); $allowedMimes = [ 'image/png' => 'png', 'image/jpeg' => 'jpg' ]; if (!array_key_exists($mime, $allowedMimes)) { die("Type d'image invalid"); } /* Verify image structure */ $imageInfo = getimagesize($_FILES['image']['tmp_name']); if ($imageInfo === false) { die("Le fichier n'est pas une image valide"); } /* Re-encode image to destroy polyglots */ $ext = $allowedMimes[$mime]; $imageName = bin2hex(random_bytes(16)) . '.' . $ext; $uploadPath = __DIR__ . "/uploads/" . $imageName; if ($mime === 'image/png') { $img = imagecreatefrompng($_FILES['image']['tmp_name']); imagepng($img, $uploadPath); } else { $img = imagecreatefromjpeg($_FILES['image']['tmp_name']); imagejpeg($img, $uploadPath, 90); } imagedestroy($img); } /* Store comment */ $stmt = $pdo->prepare("INSERT INTO posts (message, image, ip) VALUES (?, ?, ?)"); $stmt->execute([ htmlspecialchars($_POST['message'], ENT_QUOTES, 'UTF-8'), $imageName, $ip ]); header("Location: index.php");