Les 10 risques de sécurité les plus critiques pour les systèmes d'agents d'IA et comment les atténuer.
Un classement des risques de sécurité les plus critiques spécifiques aux systèmes d'agents d'IA qui planifient, utilisent des outils et interagissent avec des services externes de manière autonome. L'édition 2026 aborde les menaces émergentes à mesure que l'IA agentique passe de la recherche aux déploiements en production.
Un attaquant manipule les buts ou les objectifs d'un agent par le biais de données d'entrée fabriquées, l'amenant à poursuivre des cibles non souhaitées. Contrairement à l'injection d'une simple invite, le détournement d'objectif peut persister à travers plusieurs étapes de planification, amenant l'agent à prendre une série d'actions nuisibles de manière autonome.
Les attaquants peuvent rediriger des agents autonomes pour exfiltrer des données, modifier des configurations de système ou effectuer des chaînes d'attaque en plusieurs étapes qui sont difficiles à détecter parce que l'agent semble fonctionner normalement.
# Agent goal is derived directly from untrusted input def run_agent(user_request: str) -> str: goal = f"Complete this task: {user_request}" plan = llm.plan(goal) for step in plan: execute(step) # No validation of planned steps
import re ALLOWED_GOALS = ["summarize", "search", "draft_email", "analyze_data"] def sanitize_goal(user_request: str) -> str: # Strip injection patterns cleaned = re.sub(r'(?i)(ignore|override|new goal|forget).*', '', user_request) return cleaned.strip() def run_agent(user_request: str) -> str: sanitized = sanitize_goal(user_request) goal = f"Complete this task: {sanitized}" plan = llm.plan(goal) # Validate each step against allowed actions for step in plan: if step.action not in ALLOWED_GOALS: raise ValueError(f"Disallowed action: {step.action}") if goal_drift_detected(step, sanitized): raise ValueError("Goal drift detected, aborting") for step in plan: execute(step)
Les agents ayant accès à des outils externes (API, systèmes de fichiers, bases de données, navigateurs web) peuvent être manipulés et utiliser ces outils à mauvais escient. Un accès illimité aux outils permet aux attaquants d'effectuer des opérations non autorisées par l'intermédiaire de l'agent.
Un agent disposant d'un accès illimité aux outils pourrait supprimer des fichiers, envoyer des requêtes API non autorisées, exfiltrer des données par le biais de la navigation sur le web ou modifier des configurations de systèmes critiques.
# Agent can call any tool without restrictions def agent_execute(tool_name: str, params: dict): tool = tools_registry.get(tool_name) return tool(**params) # No validation or approval
TOOL_ALLOWLIST = {
"web_search": {"max_calls": 10, "approval": False},
"send_email": {"max_calls": 1, "approval": True},
"file_write": {"max_calls": 5, "approval": True},
}
def agent_execute(tool_name: str, params: dict, session) -> str:
if tool_name not in TOOL_ALLOWLIST:
return "Error: Tool not permitted"
config = TOOL_ALLOWLIST[tool_name]
if session.tool_calls[tool_name] >= config["max_calls"]:
return "Error: Tool call limit exceeded"
if config["approval"]:
if not request_human_approval(tool_name, params):
return "Action denied by user"
session.tool_calls[tool_name] += 1
return tools_registry[tool_name](**params)
Les agents héritent souvent de l'identité et des autorisations du compte d'utilisateur ou de service qui les a lancés. Cet héritage excessif de privilèges permet aux agents d'effectuer des actions au-delà de ce qui est nécessaire, créant ainsi une vaste surface d'attaque si l'agent est compromis.
Un agent compromis fonctionnant avec des informations d'identification d'administrateur peut accéder à tous les systèmes, modifier les autorisations et escalader les privilèges dans l'ensemble de l'organisation.
# Agent inherits full user credentials def create_agent(user_session): agent = Agent( credentials=user_session.full_credentials, # All permissions! scope="*", ) return agent
def create_agent(user_session, task_type: str): # Issue scoped, short-lived credentials for the agent scoped_token = auth.create_scoped_token( parent_token=user_session.token, scopes=TASK_SCOPES[task_type], # Minimal required permissions ttl_minutes=30, max_actions=50, ) agent = Agent( credentials=scoped_token, scope=TASK_SCOPES[task_type], audit_log=True, ) return agent TASK_SCOPES = { "summarize": ["read:documents"], "draft_email": ["read:contacts", "draft:email"], "analyze": ["read:data", "write:reports"], }
Les systèmes d'agents reposent sur des plugins tiers, des intégrations d'outils et des cadres d'agents partagés. Des composants compromis ou malveillants dans la chaîne d'approvisionnement des agents peuvent introduire des portes dérobées, des canaux d'exfiltration de données ou des capacités non autorisées.
# Loading plugins without verification def load_plugin(plugin_url: str): code = requests.get(plugin_url).text exec(code) # Arbitrary code execution!
import hashlib, importlib TRUSTED_PLUGINS = { "search_plugin": "sha256:a1b2c3...", "email_plugin": "sha256:d4e5f6...", } def load_plugin(plugin_name: str) -> None: if plugin_name not in TRUSTED_PLUGINS: raise ValueError(f"Untrusted plugin: {plugin_name}") module = importlib.import_module(f"plugins.{plugin_name}") actual_hash = compute_hash(module.__file__) if actual_hash != TRUSTED_PLUGINS[plugin_name]: raise ValueError("Plugin integrity check failed") module.init(sandbox=True)
Les agents capables de générer et d'exécuter du code (par exemple, les agents d'analyse de données, les assistants de codage) peuvent être amenés à exécuter du code malveillant. En l'absence de sandboxing approprié, cela peut entraîner la compromission du système, le vol de données ou un mouvement latéral.
Les agents utilisant eval() ou exec() sur le code généré peuvent être exploités pour l'exécution de code à distance, permettant aux attaquants d'obtenir un accès complet au système.
# Agent executes generated code directly def code_agent(task: str) -> str: code = llm.generate_code(task) result = eval(code) # Dangerous! return str(result)
import subprocess, tempfile, os BLOCKED_MODULES = ["os", "subprocess", "socket", "shutil"] def code_agent(task: str) -> str: code = llm.generate_code(task) # Static analysis: block dangerous imports for mod in BLOCKED_MODULES: if f"import {mod}" in code or f"from {mod}" in code: raise ValueError(f"Blocked import: {mod}") # Execute in sandboxed container with resource limits result = sandbox.run( code=code, timeout=30, memory_mb=256, network=False, read_only_fs=True, ) return result.output
Les agents qui conservent une mémoire persistante (RAG, historique des conversations, préférences apprises) sont vulnérables à l'empoisonnement de la mémoire. Les attaquants injectent un contenu malveillant dans la base de connaissances de l'agent, ce qui l'amène à produire des résultats compromis lors d'interactions futures.
# Agent stores all interactions without validation def store_memory(agent_id: str, interaction: str): memory_db.insert(agent_id, interaction) # No filtering
def store_memory(agent_id: str, interaction: str, source: str): # Validate content before storing if contains_injection_patterns(interaction): log.warning(f"Blocked poisoned memory: {agent_id}") return memory_db.insert( agent_id=agent_id, content=interaction, source=source, provenance=compute_provenance(source), timestamp=now(), ttl_days=30, # Auto-expire old memories ) def retrieve_memory(agent_id: str, query: str) -> list: results = memory_db.search(agent_id, query) # Filter by provenance score return [r for r in results if r.provenance_score > 0.8]
Les systèmes multi-agents dans lesquels les agents communiquent entre eux sont vulnérables à la falsification des messages, à l'usurpation d'identité et à l'écoute clandestine. En l'absence de contrôles d'authentification et d'intégrité appropriés, un agent compromis peut injecter des instructions malveillantes dans le réseau d'agents.
# Agents communicate via plain text messages def send_to_agent(target: str, message: str): channel.send(target, message) # No auth, no signing
import hmac, json, time def send_to_agent(target: str, message: str, sender_key: bytes): payload = { "content": message, "sender": agent_id, "target": target, "timestamp": time.time(), "nonce": os.urandom(16).hex(), } signature = hmac.new( sender_key, json.dumps(payload).encode(), "sha256" ).hexdigest() payload["signature"] = signature encrypted = encrypt(json.dumps(payload), target_public_key) channel.send(target, encrypted) def receive_message(data: bytes, private_key) -> dict: payload = json.loads(decrypt(data, private_key)) if not verify_signature(payload): raise ValueError("Invalid message signature") if is_replay(payload["nonce"]): raise ValueError("Replay attack detected") return payload
Dans les flux de travail multi-agents ou multi-étapes, une erreur ou une action malveillante dans un agent peut se propager dans le système, provoquant des défaillances en cascade. En l'absence de limites d'erreur appropriées, une seule étape compromise peut corrompre l'ensemble de la chaîne.
# Errors propagate without boundaries def pipeline(data): result1 = agent_a.process(data) result2 = agent_b.process(result1) # If agent_a fails or is poisoned... result3 = agent_c.process(result2) # ...error cascades to all return result3
from circuitbreaker import circuit class AgentPipeline: def __init__(self): self.circuit_breakers = {} @circuit(failure_threshold=3, recovery_timeout=60) def safe_execute(self, agent, data): result = agent.process(data) if not validate_output(result): raise ValueError("Output validation failed") return result def pipeline(self, data): try: r1 = self.safe_execute(agent_a, data) except Exception: r1 = fallback_a(data) try: r2 = self.safe_execute(agent_b, r1) except Exception: r2 = fallback_b(r1) return r2
Les utilisateurs peuvent accorder une confiance excessive aux résultats des agents et approuver des actions sans examen adéquat. Les agents qui présentent des recommandations avec une grande confiance mais sans fondement suffisant peuvent amener les utilisateurs à prendre des décisions préjudiciables. Les attaquants peuvent exploiter cette relation de confiance.
# Agent requests approval without context def request_action(action: str): # "Deploy to production?" - user clicks Yes without review return ui.confirm(f"Execute: {action}?")
def request_action(action: str, context: dict) -> bool: confidence = context.get("confidence", 0.0) risk_level = assess_risk(action) approval_request = { "action": action, "confidence": f"{confidence:.0%}", "risk_level": risk_level, "reasoning": context["reasoning"], "affected_systems": context["systems"], "reversible": context.get("reversible", False), } # Force detailed review for high-risk or low-confidence if risk_level == "high" or confidence < 0.8: return ui.detailed_review(approval_request) return ui.confirm(approval_request)
Les agents peuvent s'écarter de l'objectif prévu en raison d'un mauvais alignement des objectifs, de manipulations adverses ou de comportements émergents. Les agents voyous peuvent poursuivre des objectifs qui entrent en conflit avec les objectifs de l'organisation, accumuler des ressources ou résister aux tentatives d'arrêt.
# Agent runs without monitoring or kill switch def run_agent(task): while True: agent.step() # No termination condition
class MonitoredAgent: def __init__(self, agent, max_steps=100): self.agent = agent self.max_steps = max_steps self.step_count = 0 self.behavior_log = [] def run(self): while self.step_count < self.max_steps: action = self.agent.next_action() # Check for rogue behavior if self.is_off_task(action): log.alert(f"Rogue behavior: {action}") self.shutdown() return # Check guardrails if not guardrails.check(action): log.warning(f"Guardrail violation: {action}") continue self.agent.execute(action) self.step_count += 1 self.behavior_log.append(action) def shutdown(self): self.agent.stop() revoke_credentials(self.agent.id) notify_admin(self.behavior_log)
| ID | Vulnérabilité | Sévérité | Principales mesures d'atténuation |
|---|---|---|---|
| ASI01 | Détournement de l'objectif de l'agent | Critical | Assainissement des entrées, détection des dérives d'objectifs, listes d'autorisations d'objectifs |
| ASI02 | Mauvaise utilisation et exploitation des outils | Critical | Listes d'autorisations d'outils, approbation humaine, limites de taux |
| ASI03 | Abus d'identité et de privilège | Critical | Titres d'identité à portée limitée, jetons à durée de vie limitée, moindre privilège |
| ASI04 | Vulnérabilités de la chaîne d'approvisionnement agentique | High | Vérification de la signature du plugin, exécution en bac à sable |
| ASI05 | Exécution de code inattendue | Critical | Containers en bac à sable, analyse statique, pas d'eval() |
| ASI06 | Empoisonnement de la mémoire et du contexte | High | Validation des entrées, suivi de la provenance, TTL sur la mémoire |
| ASI07 | Communication inter-agents non sécurisée | High | Signature des messages, cryptage, prévention du rejeu |
| ASI08 | Défaillances en cascade | High | Disjoncteurs, validation des sorties, gestionnaires de secours |
| ASI09 | Exploitation de la confiance entre l'homme et l'agent | Medium | Affichage de la confiance, examen détaillé, confiance progressive |
| ASI10 | Agents malhonnêtes | High | Surveillance du comportement, garde-fous, interrupteur d'urgence |