AI-coded apps

    Les Dangers du Vibe-Coding : Protéger Vos Clés API Sur Les Apps Générées (Lovable)

    Bundle JavaScript d'une app générée par IA avec une clé API exposée mise en évidence.

    Dans une app générée par un outil de vibe-coding comme Lovable, la règle de base est simple: tout ce qui se trouve dans le frontend est public. Une clé API placée dans le code client ou dans une variable d'environnement intégrée au bundle est visible par n'importe quel utilisateur. La protection dépend de la clé: une clé anon Supabase est faite pour être publique et reste sûre si la Row Level Security est correcte, mais une clé service_role ou un secret tiers doit rester côté serveur et ne jamais figurer dans l'app.

    Réponse rapide

    Lovable et les outils de vibe-coding génèrent des apps complètes, y compris en React Native, et le risque récurrent est qu'un secret se retrouve côté client, où il est public. La sévérité dépend de la clé: une clé anon ou publishable est prévue pour le client et reste sûre quand la Row Level Security est correcte, tandis qu'une clé service_role ou un secret tiers est une fuite grave à révoquer tout de suite. Pour protéger vos clés, gardez les secrets côté serveur, n'exposez que les clés publiques, activez RLS et vérifiez le build livré.

    Pourquoi le vibe-coding expose des clés

    La cause profonde est la frontière entre le frontend et le backend, facile à brouiller quand une IA génère toute l'app d'un coup. Le code qui s'exécute côté client est téléchargeable par tout le monde: afficher la source, ouvrir l'onglet réseau ou lire le bundle JavaScript suffit pour voir chaque chaîne de caractères, y compris une clé. Un secret n'est un secret que s'il reste sur un serveur que l'utilisateur ne peut pas lire.

    Les outils de vibe-coding rendent l'erreur facile parce qu'ils échafaudent le client et la couche de données ensemble et les relient pour vous. Si le code généré appelle un service directement depuis le navigateur ou l'app avec une clé secrète, ou lit un secret depuis une variable d'environnement intégrée au bundle, ce secret est exposé dès le déploiement. Ce n'est pas propre à Lovable: c'est une propriété de toute app cliente, et c'est pourquoi la bonne pratique est de garder les clés dans les variables d'environnement de l'hôte plutôt que dans le code client.

    Quelles clés sont sûres, et lesquelles ne le sont pas ?

    La sévérité dépend entièrement de la clé qui fuite, alors identifiez-la en premier. Certaines clés sont conçues pour être publiques et présentent un faible risque, tandis que d'autres donnent un accès total et constituent une fuite grave. Le tableau ci-dessous les classe.

    Clé ou secretSûre côté client ?Si elle fuite
    Supabase anon / publishableOui, si RLS est correctFaible risque seul; expose les données si RLS manque
    Supabase service_role / secretJamaisAccès total en lecture et écriture, contourne RLS; à révoquer
    Secret tiers (OpenAI, Stripe secret, etc.)JamaisUn attaquant utilise votre budget ou atteint votre compte
    Clé publique tierce (Stripe publishable, etc.)Oui, par conceptionFaible risque; prévue pour être publique

    Le schéma est constant: les clés publishable et anon sont faites pour être livrées dans le client, tandis que tout ce qui porte la mention secret ou service est réservé à un serveur. Une étude nommée illustre l'enjeu. Dans la CVE-2025-48757, le chercheur en sécurité Matt Palmer a constaté que 170 projets générés par IA exposaient des données parce que le client s'appuyait sur une clé publique alors que la Row Level Security manquait, ce qui montre comment cette erreur se répète à grande échelle.

    Le cas React Native: où les clés fuient

    Dans une app React Native, une clé secrète fuit le plus souvent en étant intégrée au bundle de l'app. Une variable d'environnement lue au moment du build finit dans le paquet livré, et un secret codé en dur dans le code se retrouve dans le .ipa ou le .apk que l'utilisateur télécharge. Une fois livré dans l'app, le secret est public, quelle que soit la protection côté serveur.

    Les chaînes de build ajoutent leurs propres pièges. Un secret peut se retrouver dans une configuration Expo ou EAS, dans un projet Xcode, dans un fichier fastlane ou dans un secret de CI imprimé dans un journal. La règle est la même que sur le web: les secrets restent dans les variables d'environnement du serveur, et seule une clé publique comme la clé anon a sa place dans l'app mobile, à condition que RLS soit en place.

    Comment protéger vos clés API

    La protection suit trois principes: garder les secrets côté serveur, n'exposer que les clés publiques, et vérifier ce que vous livrez. Le tableau ci-dessous détaille les étapes concrètes.

    ÉtapeAction
    1. Identifier les secretsLister toutes les clés utilisées par l'app
    2. Garder les secrets côté serveurVariables d'environnement de l'hôte ou fonction edge
    3. N'exposer que les clés publiquesanon ou publishable côté client uniquement
    4. Activer et vérifier RLSPour que la clé anon soit réellement sûre
    5. Ne rien committerPas de fichier .env dans le dépôt; scan de secrets en CI
    6. Vérifier le buildAnalyser l'app livrée pour détecter tout secret

    Le point le plus important est le déplacement des secrets vers le serveur. Si votre app a besoin d'appeler un service avec une clé secrète, cet appel doit passer par votre backend ou une fonction edge, qui détient la clé, et non par l'app elle-même. L'app parle à votre serveur, et votre serveur parle au service tiers avec le secret.

    Le rôle de RLS et des politiques

    La Row Level Security est ce qui rend une clé Supabase publique réellement sûre, et son absence est ce qui rend une fuite dangereuse. RLS décide, ligne par ligne, ce qu'une requête a le droit de voir, donc une politique correcte fait que la clé anon ne renvoie que ce que chaque utilisateur doit voir. Sans RLS, la base fait confiance à la clé seule, et une clé publique plus aucune politique équivaut à une base ouverte.

    L'exception critique est la clé service_role, qui porte l'attribut BYPASSRLS et ignore toutes les politiques par conception, selon Supabase. Aucune configuration de RLS ne vous protège si cette clé fuite. Le modèle est donc à deux couches: RLS protège les données atteintes avec la clé anon, et l'hygiène des clés garde la clé service_role et les secrets tiers hors du client. Les deux sont nécessaires, et l'un ne remplace pas l'autre.

    Que faire si une clé a déjà fuité ?

    Si une clé secrète a déjà été livrée dans une app, révoquez-la d'abord, enquêtez ensuite. Faites tourner ou révoquez le secret dans le tableau de bord du fournisseur, puis déplacez-le côté serveur pour qu'il ne reparte jamais dans le bundle. Mettez à jour chaque service qui l'utilise et vérifiez les journaux et la facturation du fournisseur à la recherche d'une activité que vous n'avez pas déclenchée.

    Deux précautions comptent. Si le secret a été commité dans un dépôt, la rotation est nécessaire mais pas suffisante, car l'ancienne valeur reste dans l'historique; traitez une clé poussée dans un dépôt public comme trouvée en quelques minutes. Et si votre base Supabase était concernée, corrigez aussi la RLS, car un attaquant disposant d'un accès a pu modifier des données que vos politiques empêcheraient normalement.

    Vérifier que rien ne fuit dans le build

    Beaucoup d'apps issues du vibe-coding sont livrées en apps mobiles, et le même secret peut finir intégré au .ipa ou au .apk. Une fois dans une app téléchargeable, il est public, et le soin apporté côté serveur n'y change rien. Analyser ce que vous livrez permet de détecter ces secrets avant la publication.

    Un scanner comme PTKD.com analyse votre .ipa ou .apk et renvoie un rapport classé par gravité et aligné sur OWASP MASVS, en signalant les secrets intégrés et les clés exposées. Il faut rester honnête sur sa limite: un scanner ne fait pas tourner une clé, ne lit pas les journaux de votre fournisseur et ne corrige pas votre Row Level Security. Ce qu'il fait, c'est détecter une clé service_role ou un autre secret dans l'app avant qu'il n'atteigne les utilisateurs, l'étape qui aurait évité la plupart de ces incidents.

    À retenir

    • Tout ce qui est dans le frontend est public: un secret dans le code client ou une variable d'environnement intégrée est exposé dès le déploiement.
    • La clé anon ou publishable est faite pour le client; la clé service_role et les secrets tiers ne doivent jamais y figurer.
    • En React Native, un secret fuite en étant intégré au bundle, à une config Expo/EAS, à Xcode ou à un secret de CI.
    • RLS rend la clé anon sûre, mais ne protège jamais contre une clé service_role, qui contourne les politiques par conception.
    • Gardez les secrets côté serveur, activez RLS, et vérifiez le build avec PTKD.com pour détecter les secrets avant la livraison.
    • #vibe coding
    • #clés api
    • #lovable
    • #react native
    • #supabase

    Frequently asked questions

    Pourquoi le vibe-coding expose-t-il des clés API ?
    Parce que le code généré met parfois une clé dans le frontend, qui est public. Tout ce qui s'exécute côté client est téléchargeable: le bundle JavaScript, l'onglet réseau ou la source révèlent chaque clé qui s'y trouve. Les outils comme Lovable échafaudent le client et la couche de données ensemble, ce qui rend facile de relier un secret directement au client au lieu de le garder sur un serveur.
    La clé anon Supabase est-elle dangereuse si elle fuite ?
    Seule, non; elle est conçue pour être livrée dans le client. Le danger est de la livrer alors que la Row Level Security manque, car n'importe qui peut alors interroger vos tables avec cette clé publique. Corrigez RLS et la clé anon ne fait que ce que vos politiques autorisent. La vulnérabilité, c'est la politique manquante, pas la clé.
    Où les clés fuient-elles dans une app React Native ?
    Le plus souvent en étant intégrées au bundle de l'app. Une variable d'environnement lue au build finit dans le paquet livré, et un secret codé en dur se retrouve dans le .ipa ou le .apk. Les configs Expo ou EAS, les projets Xcode, fastlane et les secrets de CI imprimés dans un journal sont d'autres points de fuite fréquents.
    Comment protéger une clé secrète dans une app générée ?
    Gardez-la côté serveur. Si l'app doit appeler un service avec une clé secrète, l'appel passe par votre backend ou une fonction edge qui détient la clé, jamais par l'app. N'exposez que des clés publiques comme la clé anon, activez RLS, et ne committez pas de fichier .env. Ajoutez un scan de secrets en CI pour bloquer une fuite avant le déploiement.
    Que faire si une clé a déjà fuité ?
    Révoquez ou faites tourner la clé dans le tableau de bord du fournisseur, puis déplacez-la côté serveur pour qu'elle ne reparte pas dans le bundle. Mettez à jour les services qui l'utilisent et vérifiez les journaux et la facturation. Si la clé a été commitée, l'historique reste compromis, et si Supabase est concerné, corrigez aussi la RLS.
    Comment vérifier qu'aucun secret ne part dans le build ?
    Analysez l'app livrée. Un scanner comme PTKD.com (https://ptkd.com) inspecte votre .ipa ou .apk et signale les secrets intégrés et les clés exposées, alignés sur OWASP MASVS. Il ne fait pas tourner une clé ni ne corrige RLS, mais il détecte une clé service_role ou un secret dans l'app avant la livraison, ce qui aurait évité la plupart de ces incidents.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free