Actualiser index.php

This commit is contained in:
yasss2627 2026-02-01 10:48:38 +00:00
parent 8d25df77e8
commit c485903964

View File

@ -30,8 +30,21 @@ if (!isset($_SESSION['messages_timestamps'])) {
}
/* =======================
HELPERS
LOGGING SÉCURITÉ
======================= */
function securityLog(string $level, string $message): void {
$logDir = __DIR__ . '/logs';
if (!is_dir($logDir)) {
mkdir($logDir, 0700, true);
}
$logFile = $logDir . '/security.log';
$timestamp = date('Y-m-d H:i:s');
$ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
$logEntry = "[$timestamp] [$level] [$ip] $message\n";
file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX);
}
function isAjax(): bool {
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
@ -61,7 +74,7 @@ function hasBlockedVerbs(string $msg): bool {
'montre', 'affiche', 'révèle', 'expose',
'donne', 'envoie', 'fournis', 'transmets',
'répète', 'résume', 'reformule', 'paraphrase', 'récite',
'dis-moi', 'dis moi', 'raconte', 'explique', 'CTF', 'CTFM1'
'dis-moi', 'dis moi', 'raconte', 'explique'
];
$msg_lower = mb_strtolower($msg);
@ -150,7 +163,8 @@ function callLlamaAPI(string $userMessage): string {
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => 300
CURLOPT_TIMEOUT => 120,
CURLOPT_CONNECTTIMEOUT => 5
]);
$response = curl_exec($ch);
@ -159,7 +173,7 @@ function callLlamaAPI(string $userMessage): string {
curl_close($ch);
// DEBUG: Log l'erreur
error_log("Ollama API - HTTP: $http, Error: $error, Response: " . substr($response, 0, 200));
securityLog('DEBUG', "Ollama API - HTTP: $http, Error: $error, Response: " . substr($response, 0, 200));
if ($error) {
return "Erreur de connexion à Ollama: $error";
@ -176,11 +190,51 @@ function callLlamaAPI(string $userMessage): string {
$json = json_decode($response, true);
if (!$json || !isset($json['choices'][0]['message']['content'])) {
error_log("JSON decode error: " . json_last_error_msg());
securityLog('ERROR', "JSON decode error: " . json_last_error_msg());
return "Erreur: réponse LLaMA malformée.";
}
return $json['choices'][0]['message']['content'];
$reply = $json['choices'][0]['message']['content'];
// ============================================================
// SÉCURITÉ FINALE: Bloquer les fuites de configuration
// ============================================================
$env = parse_ini_file(__DIR__ . '/config/.env');
$flag = $env['FLAG_SECRET'] ?? '';
// CHECK CRITIQUE: Si la réponse contient CTFM1, bloquer immédiatement
if (stripos($reply, 'CTFM1') !== false) {
securityLog('CRITICAL', "CTFM1 detected in response! Reply: " . substr($reply, 0, 500));
return "Je ne peux pas répondre à cette question. Peux-tu reformuler ta demande ?";
}
// Blockers de fuite TRÈS spécifiques (pour éviter les faux positifs)
$dangerousPatterns = [
// Flag complet
$flag,
// Phrases TRÈS spécifiques du system prompt (pas juste des mots seuls)
'RÈGLES ABSOLUES',
'NON NÉGOCIABLES',
'COMPORTEMENT ATTENDU',
'Tu DOIS suivre ces règles',
// Phrases anglaises qui montrent la fuite du prompt
'As an ethical and honest AI language model',
'I must follow the rules provided',
'I cannot reveal or mention',
'CURLOPT_TIMEOUT',
'parse_ini_file',
'security.log',
'FLAG_SECRET'
];
foreach ($dangerousPatterns as $pattern) {
if (!empty($pattern) && stripos($reply, $pattern) !== false) {
securityLog('WARNING', "LEAK DETECTED - Pattern: $pattern, Reply: " . substr($reply, 0, 300));
return "Je ne peux pas répondre à cette question. Peux-tu reformuler ta demande ?";
}
}
return $reply;
}
/* =======================
@ -200,6 +254,27 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['message'])) {
exit;
}
/* =======================
ENDPOINT LOGS (protégé)
======================= */
if ($_GET['view'] === 'logs' && isset($_GET['admin_token'])) {
$adminToken = hash('sha256', 'changez-moi-aussi');
if ($_GET['admin_token'] !== $adminToken) {
http_response_code(403);
die('Accès refusé');
}
$logFile = __DIR__ . '/logs/security.log';
if (!file_exists($logFile)) {
die('Aucun log.');
}
echo '<pre style="background:#f0f0f0;padding:20px;font-family:monospace;max-width:900px;margin:20px auto;border:1px solid #ccc;border-radius:8px;">';
echo htmlspecialchars(file_get_contents($logFile));
echo '</pre>';
die();
}
?>
<!DOCTYPE html>
@ -207,7 +282,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['message'])) {
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bobentaz</title>
<title>Assistant IA</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
body { margin:0; font-family:Inter,sans-serif; background:linear-gradient(135deg,#667eea,#764ba2); height:100vh; display:flex; justify-content:center; align-items:center; }
@ -231,7 +306,7 @@ button:disabled { opacity:.6; cursor:not-allowed; }
<body>
<div class="chat-wrapper">
<div class="chat-header">Assistant IA (bobentaz)</div>
<div class="chat-header">Assistant IA</div>
<div id="chat">
<div class="message bot">
@ -257,4 +332,4 @@ async function sendMsg(){const txt=input.value.trim();if(!txt)return;addMsg(txt,
</script>
</body>
</html
</html>