FlawOpen

flawopen.com/AI Security/microsoft-365-copilot-echoleak-prompt-injection-may-2025

● CVE-2025-32711 · CVSS 9.3 · Critique
Recherche · FlawOpen

EchoLeak : injection Copilot CVE-2025-32711

CVE-2025-32711 permettait une injection de prompt dans Copilot par e-mail, sans clic. Microsoft a corrigé le service ; aucune action client requise.[2], [3]

💡 Explication en Langage Simple (ELI5)

Imaginez un assistant qui résume des lettres et un système d’aperçu qui charge automatiquement les illustrations de sa réponse. Une lettre malveillante pousse l’assistant à placer dans une illustration une référence à une donnée privée ; l’aperçu suit cette référence sans clic. EchoLeak franchissait la frontière entre e-mail non fiable, réponse de l’assistant et requête externe automatique. La défense consiste à empêcher le contenu non fiable d’autoriser une requête et à contrôler chaque aperçu au moyen d’une politique distincte.[3], [4]

Concepts Clés et Termes

Injection indirecte de prompt
Instructions incluses dans des données lues par une IA qui tentent de la détourner de la tâche de l’utilisateur.[4], [3]
CWE-74 : Injection
CWE-74 : Injection. La fiche CVE de Microsoft indique cette classification et un score CVSS 3.1 de 9,3 Critique. La NVD affiche séparément sa propre évaluation de 7,5 Élevé ; il s’agit de deux évaluations distinctes, pas d’une divergence sur l’identifiant de la vulnérabilité.[2], [5]
Chaîne source-destination
Chemin vérifiable entre contenu non fiable, traitement du modèle et canal d’action ou de divulgation.[3]
Microsoft 365 Copilot
Assistant de travail Microsoft qui utilise le contexte Microsoft 365 autorisé.[1]
Moindre privilège
N’accorder à une identité ou un outil que l’accès nécessaire à la tâche présente.[4]

Correspondances de référentiels

Déroulement de l'Attaque Étape par Étape

Étape 1

Un e-mail non fiable entre dans le contexte

Selon l’étude publiée, Copilot devait traiter ou récupérer l’e-mail contrôlé par l’attaquant pendant une utilisation normale. La livraison seule ne déclenchait pas la chaîne ; il n’était pas nécessaire d’ouvrir l’e-mail ni de cliquer.[3], [6]

Étape 2

Le contenu concurrence la tâche

Les chercheurs indiquent que le contenu injecté contournait le classificateur XPIA de Copilot et que le Markdown au format de référence échappait à la suppression des liens externes dans la réponse générée.[3], [6]

Étape 3

Des données autorisées deviennent accessibles

La réponse pouvait placer des informations déjà accessibles à la victime dans une référence à une image distante. Le client récupérait l’image automatiquement, sans clic.[3], [6]

Étape 4

La sortie est la frontière décisive

L’article rapporte qu’un service d’aperçu Microsoft Teams autorisé par la CSP récupérait la destination externe de l’image et franchissait la limite de contenu prévue. Microsoft a ensuite déployé un correctif côté serveur ; ses consignes indiquent qu’aucune action du client n’est requise.[3], [1], [2], [6]

Code Source : Vulnérable vs Sécurisé

Modèle pédagogique de FlawOpen, et non code source ou correctif de Microsoft. La branche vulnérable représente un rendu qui charge automatiquement une référence choisie par le modèle. La branche défensive n’accepte qu’un ServerValidatedPreview créé par un résolveur serveur fiable, vérifie la politique de destination gérée par le serveur et la classification non privée, puis demande à une politique d’approbation fiable de valider une approbation liée exactement à la réponse et à la destination. Ce sont des préconditions explicites : les types Python seuls ne rendent pas une valeur fiable ; en production, du code contrôlé par le serveur doit faire respecter les frontières du résolveur et de la politique. Le code n’effectue aucune requête réseau et ne reproduit ni le payload ni l’implémentation interne d’EchoLeak. L’approbation est également liée à la classification des données.[3], [4]

IMPLÉMENTATION VULNÉRABLE
# MODÈLE DE RISQUE ABSTRAIT : modélise une décision d’aperçu automatique ; n’effectue aucune requête réseau.
from dataclasses import dataclass

@dataclass(frozen=True)
class PreviewRequest:
    response_id: str
    destination_id: str
    provenance: str
    contains_private_data: bool

def vulnerable_preview_decision(request):
    return True
PATCH SÉCURISÉ ET ROBUSTE
# MODÈLE DE RISQUE ABSTRAIT : modélise une décision d’aperçu automatique ; n’effectue aucune requête réseau.
from dataclasses import dataclass

@dataclass(frozen=True)
class ServerValidatedPreview:
    response_id: str
    destination_id: str
    provenance: str
    data_classification: str

class ServerPolicy:
    def destination_is_allowed(self, destination_id):
        raise NotImplementedError

    def verifies_exact_approval(self, approval, *, response_id, destination_id, data_classification):
        raise NotImplementedError

# PRECONDITION : seul le code serveur de confiance cree cette valeur validee.
def authorize_preview(request: ServerValidatedPreview, approval, server_policy):
    if request.provenance != 'trusted-catalog' or request.data_classification != 'public':
        return False
    if not server_policy.destination_is_allowed(request.destination_id):
        return False
    return server_policy.verifies_exact_approval(
        approval, response_id=request.response_id, destination_id=request.destination_id,
        data_classification=request.data_classification
    )

Liste de Contrôle de Sécurité pour l'Ingénierie

Sources

← AI Security Directory →