[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"BLOG_POST_fr_ai-pentest":3,"BLOG_SURROUND_fr_ai-pentest":345},{"id":4,"title":5,"authors":6,"body":9,"category":327,"date":328,"description":329,"extension":330,"image":331,"meta":332,"navigation":333,"path":334,"seo":335,"sitemap":338,"stem":339,"tags":340,"__hash__":344},"blog\u002Fblog\u002Ffr\u002Fai-pentest.md","Pentest par IA : notre retour d'expérience",[7],{"name":8},"Emilien Mantel",{"type":10,"value":11,"toc":309},"minimark",[12,16,21,24,32,41,45,57,71,80,84,87,90,93,96,99,124,128,135,138,141,145,148,151,165,168,171,180,186,190,195,198,205,210,214,217,221,224,234,238,241,244,258,262,265,268,271,283,286,289,293,296,299,302],[13,14,15],"p",{},"Retyc sert à échanger des fichiers sensibles, et notre promesse tient en une phrase : vos fichiers sont chiffrés sur\nvotre appareil, et personne d'autre que vos destinataires ne peut les lire, pas même nous. Une promesse comme celle-là,\nil faut la mettre à l'épreuve régulièrement. Jusqu'ici, nous le faisions avec des revues de code, des tests\nautomatisés et des audits par IA, mais toujours limités à de la lecture de code. Le Cyber Verification Portal\nd'Anthropic nous a permis d'aller plus loin : un vrai pentest de Retyc, mené par Claude. Voici ce que ça a donné.",[17,18,20],"h2",{"id":19},"le-cyber-verification-portal-danthropic","Le Cyber Verification Portal d'Anthropic",[13,22,23],{},"Demander à une IA de chercher des failles pose une question évidente : qu'est-ce qui empêche quelqu'un de s'en servir\ncontre les systèmes des autres ? Anthropic encadre ce type d'usage avec le Cyber Verification Portal. Il faut y être\nadmis avant de pouvoir utiliser Claude pour des travaux de sécurité offensive sur ses propres systèmes.",[13,25,26,27,31],{},"Nous y avons eu accès, et nous nous sommes fixé un cadre strict. Le pentest a porté uniquement sur notre environnement\nde développement, ",[28,29,30],"strong",{},"jamais sur la production ni sur les données de nos clients",". Il s'est appuyé sur des comptes de\ntest dédiés, répartis sur plusieurs organisations et plusieurs formules, pour vérifier l'étanchéité entre clients.\nEt chaque constat devait donner lieu à un rapport écrit : comment le reproduire, quel impact réel, quelle correction.",[13,33,34,35,40],{},"L'environnement de développement ne porte aucune des protections qui entourent la production :\nni ",[36,37,39],"external-link",{"url":38},"https:\u002F\u002Fcrowdsec.net\u002F","CrowdSec",", ni les configurations durcies de notre infrastructure.\nC'est délibéré. Nous voulions voir les défauts de l'application elle-même, sans qu'une protection périmétrique\nne vienne les masquer. Les constats qui suivent sont donc plus sévères que ce qu'un attaquant rencontrerait face\nà notre production.",[17,42,44],{"id":43},"un-démarrage-laborieux","Un démarrage laborieux",[13,46,47,48,52,53,56],{},"Tout n'a pas fonctionné du premier coup. La documentation d'Anthropic comportait des erreurs de traduction. Nos\npremiers tests avec Opus ",[49,50,51],"code",{},"5.5"," ont en réalité tourné sur Opus ",[49,54,55],{},"4.8",". Nous ne l'avons compris\nqu'avec les avertissements de l'IA elle-même.",[13,58,59,60,63,64,67,68,70],{},"La solution a été de passer sur ",[28,61,62],{},"Opus 5"," (",[49,65,66],{},"5",", pas ",[49,69,51],{},", attention à la nuance !), qui n'a déclenché aucun\navertissement. Tout ce qui suit repose sur l'audit mené avec ce modèle.",[72,73,74],"blockquote",{},[13,75,76,77,79],{},"À la date où nous écrivons, le Cyber Verification Portal ne permet pas encore d'utiliser les modèles Fable ou\nOpus ",[49,78,51],{},".",[17,81,83],{"id":82},"comment-le-pentest-sest-déroulé","Comment le pentest s'est déroulé",[13,85,86],{},"Le pentest s'est fait en plusieurs passes, dont une reprise complète qui ne réutilisait aucune conclusion de la\nprécédente, et une vérification après chaque vague de correctifs. À noter que Claude avait accès au code source afin\nd'avoir une vue complète de l'application.",[13,88,89],{},"Une règle avant tout : Claude ne devait pas se contenter de lire le code et d'en déduire des failles.",[13,91,92],{},"Côté backend, Claude a recensé l'ensemble des endpoints exposés par notre API et relu tout le code (plusieurs dizaines\nde milliers de lignes). Il a ensuite vérifié ses hypothèses en conditions réelles, avec 4 comptes répartis sur\n3 organisations, des appels anonymes et des clés d'API. Chaque constat retenu a été reproduit : aucun n'a été\nsimplement déduit de la lecture du code.",[13,94,95],{},"Côté application web, Claude a piloté un Chrome headless. Il s'est connecté,\na déverrouillé la clé de chiffrement et a réellement envoyé un fichier contenant un marqueur connu. Il a capturé\nchaque requête partie vers le serveur, pour voir ce qui quitte vraiment le navigateur.",[13,97,98],{},"Entre autres :",[100,101,102,106,109,112,115,118,121],"ul",{},[103,104,105],"li",{},"fuzzing",[103,107,108],{},"injection de headers HTTP et requêtes mal formatées",[103,110,111],{},"recherche de XSS et d'injections SQL",[103,113,114],{},"recherche de problèmes de concurrence et de race conditions",[103,116,117],{},"vérification de l'étanchéité entre organisations et entre rôles",[103,119,120],{},"vérification de la sécurité de l'API pour les intégrations (scope des clés, restriction par adresse IP)",[103,122,123],{},"tentative d'escalade de privilèges dans une organisation",[17,125,127],{"id":126},"ce-qui-a-tenu","Ce qui a tenu",[13,129,130,131,134],{},"Le plus important d'abord : ",[28,132,133],{},"le chiffrement de bout en bout a tenu",". Pendant l'upload, aucune requête ne contenait le\ncontenu du fichier, son nom ou une clé privée. Les noms et les types de fichiers sont systématiquement chiffrés.\nDéverrouiller votre clé ne déclenche qu'une seule requête, et votre phrase secrète ne quitte jamais votre navigateur.",[13,136,137],{},"L'audit a aussi confirmé que l'étanchéité entre organisations tient sur les données : un utilisateur\nne peut ni lire ni modifier les transferts, les datarooms ou les réglages d'une autre organisation.\nÀ l'intérieur d'une organisation, un membre ne peut pas s'attribuer plus de droits qu'il n'en a.\nPour l'API destinée aux intégrations, les permissions des clés et la restriction par adresse IP sont bien appliquées.\nEnfin, la connexion suit les bonnes pratiques du protocole OpenID Connect.",[13,139,140],{},"Aucune faille XSS n'a été trouvée, et aucune injection SQL n'était possible.",[17,142,144],{"id":143},"ce-qui-a-été-trouvé","Ce qui a été trouvé",[13,146,147],{},"La plupart des constats relèvent de ce qu'on appelle le durcissement : des protections en plus, qui ne corrigent pas\nune faille exploitable, mais qui limitent les dégâts d'un éventuel problème futur ou d'une erreur\nde configuration.",[13,149,150],{},"Parmi ce que nous avons corrigé ou amélioré :",[100,152,153,156,159,162],{},[103,154,155],{},"la politique de sécurité du navigateur (CSP), déjà très stricte sur les scripts : seule une exception, nécessaire au\ncomposant qui affiche les images, était plus large que besoin. Elle n'autorise plus que le code précis dont ce\ncomposant a besoin",[103,157,158],{},"un serveur qui refuse de démarrer si un secret de configuration a été oublié, au lieu de tourner avec une valeur par\ndéfaut",[103,160,161],{},"des messages d'erreur plus propres quand un jeton de connexion est incomplet",[103,163,164],{},"verrouillage explicite d'un fichier après upload dans une dataroom",[13,166,167],{},"Par contre, 2 constats sortent du lot, et autant en parler franchement.",[13,169,170],{},"Dans une dataroom, un utilisateur avec le rôle « contributeur » n'a pas le droit de supprimer de fichiers, et l'API le\nlui refusait bien. Il pouvait malgré tout arriver au même résultat par un détour : déplacer un dossier vers une\ndataroom dont il est lui-même propriétaire, puis l'y supprimer. La suppression emportait les fichiers que d'autres\nmembres avaient déposés dans ce dossier, y compris ceux du propriétaire de la dataroom d'origine, et de façon\ndéfinitive. Il manquait une vérification sur l'appartenance du dossier de destination.",[13,172,173,174,179],{},"À l'inscription par e-mail, utilisée notamment pour déposer depuis une\n",[175,176,178],"a",{"href":177},"\u002Ffr\u002Fproducts\u002Fdeposit-box","deposit box",", le code de vérification pouvait être deviné en essayant un grand nombre de\ncombinaisons : le code était trop court et rien ne plafonnait le nombre d'essais. La preuve de travail (« proof of\nwork ») exigée à chaque tentative ne suffisait pas, car un même jeton pouvait être rejoué. Le rate limit de notre\nreverse proxy réduit drastiquement la fenêtre en production, mais nous ne voulons pas faire reposer ce\ncontrôle sur lui : le nombre d'essais est plafonné, et un jeton de preuve de travail ne sert qu'une fois.",[13,181,182,185],{},[28,183,184],{},"Aucun de ces points ne permettait de lire un fichier"," : le contenu est resté chiffré de bout en bout dans tous\nles cas.\nNous les avons corrigés en priorité.",[17,187,189],{"id":188},"les-faux-positifs","Les faux positifs",[191,192,194],"h3",{"id":193},"les-valeurs-par-défaut","Les valeurs par défaut",[13,196,197],{},"Claude a aussi remonté des points qui n'étaient pas de vrais problèmes de sécurité. Il a par exemple signalé que\ncertaines variables de configuration de notre API (sel, secrets...) avaient une valeur par défaut. Ces valeurs ne\nservaient qu'en développement : en production, elles sont toujours redéfinies.",[13,199,200,201,204],{},"Nous en avons quand même profité pour poser des règles dans notre configuration :\n",[28,202,203],{},"une valeur secrète n'a jamais de valeur par défaut",", et le serveur refuse de démarrer si elle manque,\nmême en développement ou dans la CI. Elle doit aussi avoir une taille minimale.",[72,206,207],{},[13,208,209],{},"Ces règles sont appliquées en production depuis la bêta de Retyc. Les inscrire explicitement dans notre\nconfiguration de développement permet de repérer un oubli avant qu'il n'arrive en production, ou dans les instances\n« on-premises » de nos clients.",[191,211,213],{"id":212},"le-mode-debug","Le mode debug",[13,215,216],{},"Claude a aussi relevé que certaines routes de l'API, réservées à nos développeurs, étaient accessibles en « mode\ndebug ». Ce mode ne peut pas être activé en production.",[191,218,220],{"id":219},"la-configuration-de-keycloak-en-développement","La configuration de Keycloak en développement",[13,222,223],{},"En local, notre infrastructure de développement tourne avec Docker Compose. À l'initialisation, les realms Keycloak\nsont importés depuis un fichier JSON par realm. Claude a noté que cette configuration n'était pas optimale : la\ndétection des attaques par force brute n'était pas activée, et les exigences sur la complexité des mots de passe\nétaient faibles.",[72,225,226],{},[13,227,228,229,233],{},"En production, ces points sont configurés correctement. Toute la configuration de Keycloak en production est\nversionnée, reproductible (par ",[36,230,232],{"url":231},"https:\u002F\u002Fopentofu.org\u002F","OpenTofu",") et auditable.",[17,235,237],{"id":236},"ce-que-nous-avons-fait-des-constats","Ce que nous avons fait des constats",[13,239,240],{},"Nous avons traité chaque constat comme un bug à part entière. Une correction par problème, pour pouvoir relire et\nvérifier chacune séparément. Un test de non-régression pour chaque correction, dont nous avons vérifié qu'il échoue\navant le correctif et passe après. Et une contrainte ferme : aucune correction ne devait créer de « breaking change ».",[13,242,243],{},"Nous avons corrigé tous les problèmes et toutes les recommandations de durcissement. D'autres améliorations\nplus lourdes sont planifiées pour les prochaines semaines.",[13,245,246,247,253,254,257],{},"Néanmoins, pour un cas particulier, nous avons dû faire une exception. Une amélioration de la dataroom a nécessité\nde modifier le comportement d'une route de l'API. Nous avons décidé de l'appliquer immédiatement. De ce fait,\ntoutes les versions de la ",[175,248,252],{"href":249,"rel":250},"https:\u002F\u002Fgithub.com\u002Fretyc\u002Fretyc-cli",[251],"nofollow","CLI Retyc"," antérieures à la version ",[49,255,256],{},"1.3.0"," ne peuvent\nplus faire d'ajout de fichiers dans une dataroom.",[17,259,261],{"id":260},"ce-que-nous-en-retenons","Ce que nous en retenons",[13,263,264],{},"Une IA ne remplace pas un audit humain. Mais relire des milliers de lignes de code, recenser des dizaines\nd'endpoints et rejouer chaque hypothèse avec plusieurs comptes, représente des jours de travail pour une équipe.",[13,266,267],{},"Chaque constat arrivait avec sa méthode de reproduction, une évaluation honnête de l'impact, y compris quand il était\nfaible, et une proposition de correction. Claude listait aussi ce qu'il avait vérifié et trouvé sain. C'est cette\npartie-là que nous n'attendions pas, et c'est celle qui nous a le plus servi.",[13,269,270],{},"La relecture humaine reste indispensable. Certaines corrections proposées auraient cassé des usages existants, et il\na fallu les discuter et les adapter avant de les appliquer.",[13,272,273,274,278,279,282],{},"Autre enseignement, sur la validation des données : nous attendions trop de\n",[36,275,277],{"url":276},"https:\u002F\u002Fpydantic.dev\u002Fdocs\u002Fvalidation\u002Flatest\u002Fget-started\u002F","Pydantic",".\n",[49,280,281],{},"EmailStr"," accepte les majuscules, et il a raison, la partie locale d'une adresse y est sensible selon la norme.\nUne chaîne contenant un octet nul est elle aussi parfaitement valide en Python, même si PostgreSQL la refuse.\nNormaliser les entrées reste à notre charge, à la frontière de l'API. Nous l'avons rendu explicite là où ça manquait.",[13,284,285],{},"Par ailleurs, afin d'améliorer et cadrer les pentests, nous allons travailler sur des skills dédiés.",[13,287,288],{},"Nous comptons refaire l'exercice régulièrement, en plus de nos revues de code et de nos tests.",[17,290,292],{"id":291},"en-résumé","En résumé",[13,294,295],{},"Cet audit a confirmé l'essentiel : vos fichiers restent chiffrés de bout en bout, illisibles par notre équipe comme\npar n'importe qui d'autre, même si une faille traînait dans notre code.",[13,297,298],{},"Sur la quasi-totalité des services de transfert et de stockage, c'est le service qui détient les clés. Le support y a\naccès, les administrateurs aussi, parfois des tiers.",[13,300,301],{},"Chez Retyc, le serveur n'a jamais les clés : même les constats les plus sérieux ne donnaient accès à aucun fichier.",[13,303,304,305,79],{},"Vous avez des questions sur la sécurité de Retyc, ou vous voulez en savoir plus sur notre démarche ?\n",[175,306,308],{"href":307},"\u002Ffr\u002Fabout\u002Fcontact-us","Écrivez-nous",{"title":310,"searchDepth":311,"depth":311,"links":312},"",2,[313,314,315,316,317,318,324,325,326],{"id":19,"depth":311,"text":20},{"id":43,"depth":311,"text":44},{"id":82,"depth":311,"text":83},{"id":126,"depth":311,"text":127},{"id":143,"depth":311,"text":144},{"id":188,"depth":311,"text":189,"children":319},[320,322,323],{"id":193,"depth":321,"text":194},3,{"id":212,"depth":321,"text":213},{"id":219,"depth":321,"text":220},{"id":236,"depth":311,"text":237},{"id":260,"depth":311,"text":261},{"id":291,"depth":311,"text":292},"Sécurité","2026-09-27","Grâce au Cyber Verification Portal d'Anthropic, nous avons fait un pentest de Retyc par Claude, sur notre environnement de développement.","md",null,{},true,"\u002Fblog\u002Ffr\u002Fai-pentest",{"title":5,"description":336,"ogTitle":5,"ogDescription":337},"Retyc a été pentesté par Claude via le Cyber Verification Portal d'Anthropic. Le chiffrement de bout en bout a tenu, les points remontés relevaient surtout du durcissement. Méthode, résultats et enseignements.","Claude a pentesté Retyc. Le chiffrement de bout en bout a tenu. Ce que nous avons appris.",{"loc":334},"blog\u002Ffr\u002Fai-pentest",[341,342,343],"audit de sécurité","pentest","intelligence artificielle","t0EbcqZxkMWXEgwvBpe4jyBNYEEZtiaptXcacnEwl-E",[331,346],{"title":347,"path":348,"stem":349,"description":350,"children":-1},"Anatomie d'un upload chiffré dans le navigateur","\u002Fblog\u002Ffr\u002Fanatomy-of-an-encrypted-upload","blog\u002Ffr\u002Fanatomy-of-an-encrypted-upload","Une paire de clés post-quantique par transfert, des morceaux de 8 Mo chiffrés un par un dans un Web Worker, une API qui refuse les clés classiques. Ce que fait le navigateur entre le moment où vous lâchez un fichier et celui où le dernier octet part, code à l'appui."]