[{"data":1,"prerenderedAt":380},["ShallowReactive",2],{"blog-fr-cors-wildcard-security-risk":3},{"id":4,"title":5,"body":6,"category":339,"cover":340,"coverAlt":341,"description":342,"draft":343,"extension":344,"faq":345,"image":361,"keywords":362,"meta":369,"navigation":370,"ogTitle":30,"path":371,"published":372,"seo":373,"stem":374,"tldr":375,"updated":372,"__hash__":379},"blog_fr\u002Fblog\u002Fcors-wildcard-security-risk.md","Un joker CORS est-il un risque de sécurité ? Rarement.",{"type":7,"value":8,"toc":327},"minimark",[9,18,26,31,34,44,47,50,54,57,63,66,72,75,79,82,85,168,175,178,182,193,196,202,207,210,214,217,220,229,232,236,239,257,263,271,278,282,307,314],[10,11,12,13,17],"p",{},"Votre scan est revenu avec une ligne qui se lit comme une alarme : votre API est\nouverte à n'importe quel site. Ou bien quelqu'un de technique a regardé ce que\nrenvoie votre serveur et vous a dit que votre application a un joker CORS,\nc'est-à-dire le caractère ",[14,15,16],"code",{},"*",", ce qui apparemment veut dire tout le monde.",[10,19,20,21,25],{},"Voici la partie que guide après guide présente de travers : ",[22,23,24],"strong",{},"le joker n'est\npresque jamais ce qui a ouvert votre API."," C'est une instruction que votre\nserveur attache à ses réponses, adressée aux navigateurs de gens installés sur\nd'autres sites, et elle arrive après que la réponse est déjà partie. Le\nrestreindre empêche la page d'un autre site de lire vos données. Cela ne change\nrien pour quiconque les lit sans navigateur du tout.",[27,28,30],"h2",{"id":29},"un-joker-cors-est-il-un-risque-de-sécurité","Un joker CORS est-il un risque de sécurité ?",[10,32,33],{},"En lui-même, presque jamais. Il en devient un dès l'instant où quelque chose de\nprivé répond derrière lui.",[10,35,36,37,39,40,43],{},"Le joker est la valeur ",[14,38,16],{}," dans un en-tête de réponse appelé\n",[14,41,42],{},"Access-Control-Allow-Origin",", et il signifie que le code de n'importe quel site\npeut lire cette réponse-là. Cela ressemble à une déclaration sur qui peut\natteindre vos données. C'est une déclaration sur qui peut lire ce que votre\nserveur a déjà envoyé.",[10,45,46],{},"L'adresse que vérifie un scan est celle depuis laquelle votre application est\nservie. Chez la plupart des builders, cette adresse distribue vos pages, vos\nimages et votre code compilé, et tout cela part vers chaque visiteur par\nconception. Un joker là-dessus accorde la permission de lire des fichiers que\nn'importe qui pouvait déjà télécharger en ouvrant votre site.",[10,48,49],{},"Le constat est donc une question et non un verdict, et la question est de savoir\nce qui se trouve derrière l'en-tête. Si la réponse est votre page d'accueil, il\nne s'est rien passé. Si la réponse est une liste de vos clients, cette liste\nétait déjà accessible à quiconque détenait l'adresse.",[27,51,53],{"id":52},"ce-que-fait-réellement-access-control-allow-origin","Ce que fait réellement Access-Control-Allow-Origin",[10,55,56],{},"Il dit au navigateur de votre visiteur si la page affichée a le droit de\nregarder une réponse que votre serveur a déjà envoyée.",[10,58,59,60,62],{},"L'ordre des choses est l'essentiel, et il va à rebours de ce que presque tout le\nmonde imagine. Une page sur un autre site exécute un morceau de code qui demande\ndes données à votre application. La requête part. Votre serveur la reçoit,\nexécute ce qu'il a à exécuter et renvoie la réponse en entier. Ce n'est\nqu'ensuite que le navigateur lit l'en-tête de cette réponse et décide s'il remet\nle contenu à la page qui l'a demandé. Le guide CORS de MDN le résume en une\nligne : le serveur doit donner son accord avec ",[14,61,42],{},"\npour partager la réponse avec le script.",[10,64,65],{},"Vos données ont quitté le bâtiment dans les deux cas. Ce que l'en-tête décide,\nc'est si un morceau de code précis, tournant dans le navigateur d'une personne\nprécise, arrive à les voir.",[67,68],"diagram",{"alt":69,"caption":70,"src":71},"Un serveur répond à deux appelants par une réponse identique. Sur la voie du haut, la réponse atteint un navigateur qui la retient à une barrière, de sorte que la page située derrière ne reçoit rien. Sur la voie du bas, il n'y a aucune barrière et la même réponse arrive intacte dans une fenêtre de terminal.","Les deux appelants obtiennent une réponse, car le serveur l'envoie avant que quoi que ce soit soit vérifié. La barrière de la voie du haut est le navigateur, et il n'y a aucun navigateur sur la voie du bas.","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fwho-reads-the-header-1600x650.png",[10,73,74],{},"Le navigateur est la seule chose dans cette histoire qui lise l'en-tête. Un\nscript sur un serveur, un outil en ligne de commande, un scraper, une\napplication mobile : aucun ne le consulte, car il a été écrit pour un navigateur\net aucun navigateur n'entre en jeu. Ils envoient la même requête, reçoivent la\nmême réponse et en lisent chaque octet.",[27,76,78],{"id":77},"restreindre-cors-ne-rend-pas-privé-un-endpoint-ouvert","Restreindre CORS ne rend pas privé un endpoint ouvert",[10,80,81],{},"Parce que CORS vit à l'intérieur des navigateurs, et que celui qui se sert dans\nvos données n'a aucune raison d'en utiliser un.",[10,83,84],{},"C'est la partie qui coûte un après-midi. On voit le constat du joker, on\nresserre l'en-tête sur son propre domaine, on redéploie, on rescanne, et\nl'adresse qui distribuait des lignes de clients distribue toujours des lignes de\nclients. Elle l'a toujours fait. Le seul appelant qui se soit jamais arrêté,\nc'était la page web de quelqu'un d'autre.",[86,87,88,109],"table",{},[89,90,91],"thead",{},[92,93,94,98,103,106],"tr",{},[95,96,97],"th",{},"Ce que quelqu'un tente",[95,99,100,101],{},"Joker ",[14,102,16],{},[95,104,105],{},"Votre domaine uniquement",[95,107,108],{},"Toute origine renvoyée en écho, identifiants autorisés",[110,111,112,125,136,148],"tbody",{},[92,113,114,118,121,123],{},[115,116,117],"td",{},"Ouvrir l'adresse dans un onglet de navigateur",[115,119,120],{},"Fonctionne",[115,122,120],{},[115,124,120],{},[92,126,127,130,132,134],{},[115,128,129],{},"La lire depuis un script ou un terminal",[115,131,120],{},[115,133,120],{},[115,135,120],{},[92,137,138,141,143,146],{},[115,139,140],{},"La page d'un autre site qui la lit",[115,142,120],{},[115,144,145],{},"Bloqué",[115,147,120],{},[92,149,150,153,159,163],{},[115,151,152],{},"Un autre site qui la lit au nom de votre utilisateur connecté",[115,154,155],{},[156,157,145],"key-verdict",{"type":158},"safe",[115,160,161],{},[156,162,145],{"type":158},[115,164,165],{},[156,166,120],{"type":167},"danger",[10,169,170,171,174],{},"Lisez deux fois la dernière ligne, car c'est là que le conseil générique\ns'effondre. Un simple joker ne peut pas servir à lire des données appartenant à\nvotre visiteur connecté. Les navigateurs refusent cette combinaison sans\ndiscuter, et le guide CORS de MDN le dit directement : si une requête porte un\ncookie et que la réponse revient avec ",[14,172,173],{},"Access-Control-Allow-Origin: *",", le\nnavigateur bloque l'accès à la réponse et signale une erreur CORS dans la\nconsole. C'est donc le joker, précisément, qui rend cette attaque-là impossible.",[10,176,177],{},"La colonne qui livre bel et bien les données d'un utilisateur connecté est la\ntroisième, et il faut pour cela que le serveur inscrive l'adresse de l'appelant\nlui-même dans sa réponse.",[27,179,181],{"id":180},"le-réglage-cors-qui-est-vraiment-dangereux","Le réglage CORS qui est vraiment dangereux",[10,183,184,185,188,189,192],{},"Un serveur qui lit l'en-tête ",[14,186,187],{},"Origin"," de la requête, écrit cette même valeur\ndans sa propre réponse et envoie ",[14,190,191],{},"Access-Control-Allow-Credentials: true"," avec\nelle.",[10,194,195],{},"Personne ne décide de faire ça. Cela arrive au bout d'un après-midi passé à\nessayer de faire marcher un joker avec des requêtes authentifiées, et à\ndécouvrir qu'il ne marchera jamais. Renvoyer en écho l'origine qui a demandé\nressemble à la solution : tout site qui devrait être autorisé l'est, les erreurs\nde console cessent, la fonctionnalité part en production. Ce que le serveur dit\nen réalité, c'est que l'appelant décide, ce qui inclut une page que personne n'a\nencore écrite.",[10,197,198,199,201],{},"Voici ce que cela permet. Votre cliente est connectée à votre application, avec\nun cookie de session dans son navigateur. Dans un autre onglet, elle ouvre un\nsite qui n'a rien à voir avec vous. Le code de ce site demande son compte à\nvotre API. Son navigateur joint le cookie, parce que joindre des cookies est ce\nque font les navigateurs. Votre serveur lit une ",[14,200,187],{}," dont il n'a jamais\nentendu parler, la tamponne dans la réponse comme permission et ajoute que les\nidentifiants sont acceptés. Le navigateur vérifie, trouve une correspondance et\nremet les données de votre cliente à une page dont elle ignorait qu'elle les\nlisait.",[67,203],{"alt":204,"caption":205,"src":206},"Une requête quitte un site inconnu en portant une étiquette rouge avec un nom et un cookie. Le serveur recopie cette même étiquette rouge dans le champ de permission de sa réponse. Le navigateur compare les deux étiquettes, les trouve identiques et laisse passer les données jusqu'à la page.","L'appelant fournit le nom, et le serveur inscrit ce nom sur le laissez-passer. Celui qui demande est sur la liste, et c'est ce qui distingue ce cas d'un joker.","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fthe-echoed-origin-1600x680.png",[10,208,209],{},"Dans notre balayage d'août 2026, cela est apparu sur 61 des 30 926 applications\noù la vérification a pu obtenir une réponse. Des trois constats CORS, c'est le\nseul qui atteigne des données situées derrière une connexion.",[27,211,213],{"id":212},"à-quelle-fréquence-un-joker-apparaît-et-qui-en-décide","À quelle fréquence un joker apparaît, et qui en décide",[10,215,216],{},"C'est surtout votre builder qui décide. Dans ce même balayage, 5 727 de ces\n30 926 applications envoyaient un joker, et le meilleur indicateur pour savoir\nsi la vôtre le fait est la plateforme qui l'a publiée.",[10,218,219],{},"La vérification CORS a signalé au moins un constat sur 5 418 des 5 419\napplications Base44 pour lesquelles elle a obtenu une réponse, et sur 8 des\n18 518 applications Lovable. Replit se situe entre les deux, avec 1 129 sur\n3 037. Un écart aussi large, c'est à cela que ressemble un réglage par défaut\nd'hébergement vu de l'extérieur : quasi total sur une plateforme, quasi absent\nsur une autre, à travers des milliers d'applications dont les propriétaires\nn'ont jamais rien coordonné.",[10,221,222,223,228],{},"Trois constats distincts composent la vérification CORS sur l'ensemble des\n30 926 applications : un joker sur 5 727 d'entre elles, une adresse qui répond\navec des données et sans connexion sur 3 852, et la forme de l'origine renvoyée\nen écho sur 61. Le total dépasse la vérification elle-même, car beaucoup\nd'applications en cumulent deux sur trois. Chaque chiffre ici provient de\n",[224,225,227],"a",{"href":226},"\u002Fresearch\u002Fvibe-coded-app-security-2026","notre scan de 30 998 applications vibe-codées en ligne",",\nqui publie chacun avec la base sur laquelle il a été mesuré.",[10,230,231],{},"Ce sur quoi vous pouvez agir se répartit de la même façon. Le joker est envoyé\npar celui qui sert votre application, et pour une application vibe-codée c'est\ngénéralement le builder. Ce qui revient quand un inconnu demande des données à\nl'une de vos adresses a été décidé à l'intérieur de votre application, par vous\nou par le builder qui écrit du code en votre nom.",[27,233,235],{"id":234},"comment-vérifier-votre-propre-application","Comment vérifier votre propre application",[10,237,238],{},"Deux choses à regarder, et la seconde est celle qui décide si tout cela compte.",[10,240,241,244,245,248,249,252,253,256],{},[22,242,243],{},"Votre application envoie-t-elle un joker ?"," Ouvrez votre application en\nproduction, appuyez sur F12 pour faire apparaître les outils de développement du\nnavigateur, cliquez sur ",[22,246,247],{},"Network"," et rechargez la page. Cliquez sur la\npremière requête de la liste et lisez le panneau ",[22,250,251],{},"Response Headers",". Une ligne\nindiquant ",[14,254,255],{},"access-control-allow-origin: *"," est le constat. Aucune ligne de ce\ngenre signifie que votre serveur ne partage rien entre origines avec personne.",[10,258,259,262],{},[22,260,261],{},"Qu'est-ce qui répond derrière ?"," Restez dans l'onglet Network et rechargez\nvotre application en étant connecté, en guettant les requêtes qui reviennent en\nJSON. Ce sont les adresses auprès desquelles votre application récupère des\ndonnées. Copiez chaque URL, ouvrez une fenêtre de navigation privée pour être\ndéconnecté, et collez-les une par une. Tout ce qui revient avec de vraies lignes\nau lieu d'une erreur ou d'une liste vide est lisible par n'importe qui sur\ninternet disposant de cette URL. C'est vrai aujourd'hui, quoi que dise votre\nen-tête CORS, et cela reste vrai après que vous l'avez resserré.",[10,264,265,266,270],{},"Notre scan gratuit fait la seconde vérification pour vous : il lit le code de\nvotre application à la recherche des adresses qu'elle appelle, interroge chacune\nsans connexion et signale celles qui ont répondu avec des données. Il prend une\nvingtaine de secondes et ne demande aucun compte :\n",[224,267,269],{"href":268},"\u002F#scan","scannez votre application",".",[10,272,273,274,270],{},"Si votre application parle à Supabase directement depuis le navigateur, il y a\nun troisième endroit à regarder, car les règles posées sur chaque table décident\nqui peut lire quelles lignes, et\n",[224,275,277],{"href":276},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","les activer ne revient pas à être protégé",[27,279,281],{"id":280},"ce-quil-faut-faire-maintenant","Ce qu'il faut faire maintenant",[283,284,285],"key-takeaways",{},[286,287,288,292,295,298,304],"ul",{},[289,290,291],"li",{},"Prenez un constat de joker comme une question sur ce qui se trouve derrière l'en-tête. Sur l'adresse depuis laquelle votre application est servie, il autorise en général la lecture de fichiers que chaque visiteur télécharge de toute façon.",[289,293,294],{},"Déconnectez-vous et ouvrez chaque adresse de données que votre application appelle. Tout ce qui renvoie de vraies lignes à un navigateur déconnecté est public pour tout le monde, quoi que dise l'en-tête.",[289,296,297],{},"Corrigez une adresse ouverte à l'adresse elle-même : exigez une connexion et répondez à un inconnu par un 401. Resserrer l'en-tête CORS la laisse accessible à tout, sauf aux pages web des autres.",[289,299,300,301,303],{},"Si votre serveur renvoie en écho l'origine qui a demandé et envoie ",[14,302,191],{},", remplacez cela dès aujourd'hui par une liste de vos propres domaines. C'est le seul cas ici qui laisse un autre site lire des données au nom de votre utilisateur connecté.",[289,305,306],{},"Si l'en-tête vient de l'hébergement de votre builder et que vous ne pouvez pas le changer, consacrez ce temps aux endpoints. C'est là que sont vos données.",[10,308,309,310,270],{},"L'habitude qui vaut la peine d'être gardée, c'est le passage déconnecté sur vos\npropres adresses de données, car chaque nouvelle fonctionnalité en ajoute une et\nrien ne change à l'écran quand l'une d'elles se met à répondre. Reeve Care\nrelance ce scan contre votre application en production selon un calendrier et\nvous écrit quand un résultat se dégrade :\n",[224,311,313],{"href":312},"\u002F#pricing","ce qu'il surveille et ce qu'il coûte",[10,315,316,317,321,322,326],{},"Si vous préférez tout traiter d'un seul coup, la\n",[224,318,320],{"href":319},"\u002Fchecklist","checklist de sécurité en 10 minutes"," couvre ce point à côté du\nreste de ce qu'une application fraîchement lancée a tendance à laisser ouvert,\net ",[224,323,325],{"href":324},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","quelles clés sont sûres dans votre frontend","\nest l'autre moitié de la question avec laquelle les gens arrivent en général.",{"title":328,"searchDepth":329,"depth":329,"links":330},"",3,[331,333,334,335,336,337,338],{"id":29,"depth":332,"text":30},2,{"id":52,"depth":332,"text":53},{"id":77,"depth":332,"text":78},{"id":180,"depth":332,"text":181},{"id":212,"depth":332,"text":213},{"id":234,"depth":332,"text":235},{"id":280,"depth":332,"text":281},"Bases de la sécurité","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcover-1200x630.png","Six appelants différents atteignent un même serveur, et la même réponse repart vers chacun d'eux.","Un joker CORS est-il un risque de sécurité ? C'est souvent le réglage par défaut de votre builder, et il ne livre rien que votre serveur ne donnait déjà.",false,"md",[346,349,352,355,358],{"q":347,"a":348},"Mon scan dit que mon API est ouverte à n'importe quel site. Dois-je corriger ça ?","Regardez d'abord ce qui répond derrière. Un joker sur l'adresse depuis laquelle votre application est servie autorise généralement la lecture de vos pages, de vos images et de votre code compilé, et tout cela, chaque visiteur le télécharge de toute façon. Corrigez-le quand une adresse située derrière cet en-tête renvoie de vraies données à quelqu'un qui n'est pas connecté, et corrigez-le à cette adresse en y exigeant une connexion.",{"q":350,"a":351},"Restreindre CORS à mon propre domaine rend-il mon API privée ?","Non. CORS est une règle que les navigateurs s'appliquent à eux-mêmes, elle ne gouverne donc jamais que du code s'exécutant sur la page web de quelqu'un d'autre. Un script, une commande dans un terminal ou un scraper envoient la même requête et lisent la même réponse, car aucun d'eux ne consulte l'en-tête. Si une adresse renvoie vos données sans connexion, elle le fait pour tout le monde, quoi que dise l'en-tête.",{"q":353,"a":354},"Un autre site peut-il lire les données de mes utilisateurs connectés à cause d'un joker ?","Pas avec un simple joker. Les navigateurs refusent cette combinaison : le guide CORS de MDN indique que lorsqu'une requête porte un cookie et que la réponse revient avec Access-Control-Allow-Origin réglé sur le joker, le navigateur bloque l'accès à la réponse et journalise une erreur CORS. La version qui fonctionne, elle, est un serveur qui renvoie en écho l'origine qui a demandé, avec Access-Control-Allow-Credentials réglé sur true.",{"q":356,"a":357},"Comment changer l'en-tête CORS sur une application Lovable ou Base44 ?","Souvent vous ne pouvez pas, car l'en-tête est envoyé par l'hébergement sur lequel votre builder publie et il s'applique à toutes les applications de cette plateforme. Cela vaut la peine de le savoir avant d'y passer une semaine. Ce que vous pouvez toujours changer, c'est ce que vos propres endpoints renvoient à une requête sans connexion, et c'est de toute façon là que se situe le correctif.",{"q":359,"a":360},"Mon scan a aussi signalé des endpoints API ouverts. Est-ce le même constat ?","C'est un autre, et le plus grave des deux. Un joker décrit qui a le droit de lire une réponse. Un endpoint ouvert signifie que la réponse contenait vos données et est arrivée sans que personne se connecte. Le second est vrai pour un navigateur, pour un script et pour un inconnu muni de l'URL, et resserrer votre en-tête CORS n'y change rien.","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",[363,364,365,366,367,368],"joker cors risque de sécurité","access-control-allow-origin joker","le joker cors est-il dangereux","mauvaise configuration cors","api ouverte à n'importe quel site","access-control-allow-credentials true",{},true,"\u002Fblog\u002Fcors-wildcard-security-risk","2026-08-26",{"title":5,"description":342},"blog\u002Fcors-wildcard-security-risk",[376,377,378],"Un joker CORS n'est un risque de sécurité que lorsque quelque chose de privé répond derrière lui. Seul, il autorise la lecture de choses que tout le monde pouvait déjà télécharger.","L'en-tête est une instruction adressée au navigateur de votre visiteur, et il arrive après que la réponse est déjà partie. Personne ne le lit en dehors d'un navigateur, donc le restreindre laisse un endpoint ouvert tout aussi ouvert.","Ce qui mérite une soirée, c'est un serveur qui renvoie en écho le site qui pose la question et autorise en plus les identifiants. Celui-là laisse un autre site lire des données au nom de votre utilisateur connecté.","0C1Fu_y5xG-E0GARP7dBHqgrO-qGyKv1GvrGEnZ5E5E",1787826048205]