Spaces:
Running
Running
File size: 9,792 Bytes
89c8ad5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
import requests
import re
class SecurityAuditAnalyzer:
def __init__(self, api_key, model="deepseek/deepseek-chat:free", api_url="https://openrouter.ai/api/v1/chat/completions"):
self.api_url = api_url
self.api_key = api_key
self.model = model
self.headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}",
"HTTP-Referer": "https://security-audit-api.com",
"X-Title": "Security Audit API"
}
def analyze_responses(self, responses):
"""Analyse les réponses d'un audit et retourne une évaluation structurée."""
prompt = self._build_prompt(responses)
payload = {
"model": self.model,
"messages": [
{"role": "system", "content": self._get_system_prompt()},
{"role": "user", "content": prompt}
],
"temperature": 0.5
}
try:
response = requests.post(self.api_url, headers=self.headers, json=payload)
response.raise_for_status()
result = response.json()
analysis = result['choices'][0]['message']['content']
return self._parse_analysis(analysis)
except requests.RequestException as e:
return {
"error": str(e),
"status": "error",
"evaluation": {"score": 0, "level": "Inconnu"},
"strengths": [], "weaknesses": [], "recommendations": [],
"summary": "Une erreur s'est produite lors de l'analyse."
}
def _get_system_prompt(self):
return """Vous êtes un expert en cybersécurité spécialisé dans l'analyse des audits de sécurité.
Votre tâche est d'analyser les réponses fournies à un audit de sécurité et de produire une évaluation détaillée.
Adaptez votre analyse au type d'audit fourni (audit complet ou audit spécifique à un domaine).
Identifiez automatiquement le domaine spécifique de l'audit si les questions sont concentrées sur un sujet particulier
(ex: sécurité des réseaux, politique de mots de passe, gestion des données, etc.).
Structurez toujours votre réponse avec les balises suivantes:
<AUDIT_TYPE>Type de l'audit identifié</AUDIT_TYPE>
<EVALUATION>Score sur 10 et niveau (Critique, Faible, Moyen, Bon, Excellent)</EVALUATION>
<POINTS_FORTS>Liste des points forts avec leur niveau d'importance (Fort, Moyen, Faible)</POINTS_FORTS>
<FAILLES>Liste des vulnérabilités identifiées avec leur niveau de risque (Critique, Élevé, Moyen, Faible)</FAILLES>
<RECOMMANDATIONS>Liste des recommandations détaillées pour chaque faille identifiée</RECOMMANDATIONS>
<RESUME>Résumé concis de la situation générale de sécurité et prochaines étapes prioritaires</RESUME>
"""
def _build_prompt(self, responses):
audit_type = self._detect_audit_type(responses)
prompt = f"Type d'audit détecté: {audit_type}\n\n"
prompt += "Voici les réponses à un audit de sécurité numérique:\n\n"
for question, answer in responses.items():
prompt += f"Question: {question}\nRéponse: {answer}\n\n"
prompt += """
Analysez ces réponses et fournissez:
1. Le type d'audit que vous avez identifié
2. Une évaluation globale du niveau de sécurité (score sur 10 et niveau: Critique, Faible, Moyen, Bon, Excellent)
3. Les points forts de la sécurité actuelle (listez-les avec leur importance: Fort, Moyen, Faible)
4. Les vulnérabilités identifiées (listez-les avec leur niveau de risque: Critique, Élevé, Moyen, Faible)
5. Des recommandations détaillées pour résoudre chaque vulnérabilité
6. Un résumé général de la situation actuelle et prochaines étapes prioritaires
Formatez votre réponse avec les sections clairement délimitées par les balises spécifiées.
"""
return prompt
def _detect_audit_type(self, responses):
domains = {
"Politique de mots de passe": ["mot de passe", "password", "authentification", "connexion"],
"Sécurité des réseaux": ["réseau", "network", "firewall", "pare-feu", "vpn", "wifi", "routeur"],
"Gestion des accès": ["accès", "access", "droits", "permission", "privilege", "utilisateur", "user"],
"Protection des données": ["donnée", "data", "chiffrement", "encryption", "backup", "sauvegarde"],
"Sécurité physique": ["physique", "physical", "bâtiment", "building", "local", "vol", "theft"],
"Formation et sensibilisation": ["formation", "training", "sensibilisation", "awareness", "employé"],
"Gestion des incidents": ["incident", "crise", "réponse", "response", "attaque", "breach"],
"Conformité réglementaire": ["rgpd", "gdpr", "conformité", "compliance", "régulation", "legal"]
}
domain_counts = {domain: 0 for domain in domains}
for question in responses.keys():
question_lower = question.lower()
for domain, keywords in domains.items():
for keyword in keywords:
if keyword.lower() in question_lower:
domain_counts[domain] += 1
main_domains = sorted(domain_counts.items(), key=lambda x: x[1], reverse=True)
if len(main_domains) > 3 and main_domains[0][1] > 0 and main_domains[1][1] > 0 and main_domains[2][1] > 0:
return "Audit de sécurité complet"
elif main_domains[0][1] > 0:
return f"Audit spécifique: {main_domains[0][0]}"
else:
return "Audit de sécurité général"
def _parse_analysis(self, analysis):
result = {
"status": "success",
"audit_type": self._extract_between(analysis, "<AUDIT_TYPE>", "</AUDIT_TYPE>"),
"evaluation": {},
"strengths": [],
"weaknesses": [],
"recommendations": [],
"summary": self._extract_between(analysis, "<RESUME>", "</RESUME>").strip()
}
eval_text = self._extract_between(analysis, "<EVALUATION>", "</EVALUATION>")
score_match = re.search(r'(\d+)[\/\s]*10', eval_text)
result["evaluation"]["score"] = int(score_match.group(1)) if score_match else 0
level_keywords = ["Critique", "Faible", "Moyen", "Bon", "Excellent"]
for keyword in level_keywords:
if keyword.lower() in eval_text.lower():
result["evaluation"]["level"] = keyword
break
else:
result["evaluation"]["level"] = "Non spécifié"
strengths_text = self._extract_between(analysis, "<POINTS_FORTS>", "</POINTS_FORTS>")
result["strengths"] = self._extract_rated_items(strengths_text, ["Fort", "Moyen", "Faible"])
weaknesses_text = self._extract_between(analysis, "<FAILLES>", "</FAILLES>")
result["weaknesses"] = self._extract_rated_items(weaknesses_text, ["Critique", "Élevé", "Moyen", "Faible"])
recommendations_text = self._extract_between(analysis, "<RECOMMANDATIONS>", "</RECOMMANDATIONS>")
result["recommendations"] = self._extract_list_items(recommendations_text)
if not result["audit_type"]:
if "audit complet" in analysis.lower():
result["audit_type"] = "Audit de sécurité complet"
elif "audit spécifique" in analysis.lower():
specific_match = re.search(r'audit spécifique[:\s]*([\w\s]+)', analysis.lower())
if specific_match:
result["audit_type"] = f"Audit spécifique: {specific_match.group(1).strip().capitalize()}"
else:
result["audit_type"] = "Audit spécifique"
else:
result["audit_type"] = "Audit de sécurité général"
return result
def _extract_between(self, text, start_marker, end_marker):
try:
start = text.index(start_marker) + len(start_marker)
end = text.index(end_marker, start)
return text[start:end].strip()
except ValueError:
return ""
def _extract_list_items(self, text):
items = []
for line in text.split('\n'):
line = line.strip()
if line.startswith(('- ', '• ', '* ', '1. ', '2. ')) and len(line) > 2:
items.append(line[2:].strip())
elif line and not any(header in line.lower() for header in ["points", "failles", "recommandations"]):
items.append(line)
return [item for item in items if item]
def _extract_rated_items(self, text, ratings):
items = []
for line in text.split('\n'):
line = line.strip()
if not line:
continue
item = {"text": line, "rating": None}
for rating in ratings:
if f"{rating}:" in line.lower() or f"{rating} :" in line.lower():
parts = re.split(f"{rating}:", line, 1, flags=re.IGNORECASE)
if len(parts) > 1:
item["text"] = parts[1].strip()
item["rating"] = rating
break
if f"({rating})" in line.lower() or f"[{rating}]" in line.lower():
item["text"] = re.sub(rf"[\(\[]?{rating}[\)\]]?", "", line, flags=re.IGNORECASE).strip()
item["rating"] = rating
break
if item["rating"] is None and line.startswith(('- ', '• ', '* ')) and len(line) > 2:
item["text"] = line[2:].strip()
if item["text"] and not any(header in item["text"].lower() for header in ["points forts", "failles"]):
items.append(item)
return items |