Security

    Clés API Exposées en Frontend : Dangers et Solutions pour Apps Mobiles

    Extraction d'une clé API en clair depuis le bundle JavaScript d'une application React Native.

    Une clé API placée dans le front-end d'une application mobile n'est jamais réellement secrète. N'importe qui peut l'extraire en décompilant l'app, en lisant le bundle JavaScript ou en interceptant le trafic réseau, car le téléphone de l'utilisateur n'est pas un environnement de confiance. Les clés vraiment sensibles doivent donc vivre sur un backend, pas dans l'app. Les clés qui doivent rester côté client, comme une clé de cartographie, doivent être restreintes chez le fournisseur. Un fichier .env ne protège rien dans une app mobile.

    Réponse rapide

    Une clé exposée dans le front-end est lisible par tout le monde, car le code de l'app est livré sur l'appareil de l'utilisateur. Selon la documentation d'Expo, les variables préfixées EXPO_PUBLIC_ sont intégrées en clair dans le bundle compilé, donc un .env ne cache aucun secret. La règle est simple : les clés secrètes, comme les clés d'API serveur, les jetons admin ou les clés privées, ne doivent jamais être dans l'app, mais sur un backend. Les clés forcément publiques, comme une clé Google Maps, doivent être restreintes par identifiant d'app et par quota. En cas de fuite, révoquez et régénérez la clé immédiatement.

    Pourquoi une clé API dans le front-end n'est jamais secrète

    Le principe de base de la sécurité mobile est que le client n'est pas un environnement de confiance. Tout ce que vous livrez dans l'app, code et clés compris, se retrouve sur l'appareil de l'utilisateur, où il peut être inspecté. Une clé dans le binaire ou le bundle est donc extractible, quel que soit l'effort déployé pour la cacher.

    Concrètement, un attaquant dispose de plusieurs chemins. Il peut décompiler l'APK ou l'IPA, lire les chaînes de caractères du bundle JavaScript, ou intercepter le trafic HTTPS avec un proxy sur un appareil qu'il contrôle. Chacune de ces méthodes révèle les clés embarquées. C'est pourquoi « cacher » une clé côté client relève de l'illusion, et non d'une véritable protection.

    Le cas de React Native et Expo

    React Native et Expo aggravent souvent le malentendu, car les développeurs supposent qu'un fichier .env fonctionne comme sur un serveur. Ce n'est pas le cas. Au moment du build, les variables d'environnement référencées dans le code sont intégrées directement dans le bundle JavaScript, en clair. La documentation d'Expo est explicite : ne stockez jamais d'informations sensibles dans des variables EXPO_PUBLIC_, car elles seront visibles dans l'application compilée.

    Le point important est que cette intégration se fait à la compilation. Une variable comme process.env.MA_CLE est remplacée par sa valeur littérale dans le bundle livré. Le fichier .env n'accompagne pas l'app ; sa valeur, elle, y est gravée. Autrement dit, un .env organise vos secrets pendant le développement, mais ne les protège pas une fois l'app distribuée aux utilisateurs.

    Clés publiques vs clés secrètes : la vraie distinction

    Toutes les clés ne se valent pas, et la première décision est de classer chaque clé comme publique ou secrète. Une clé publique est conçue pour être visible, comme une clé publishable Stripe ou une configuration Firebase ; sa présence dans le client est prévue et acceptable. Une clé secrète donne un accès privilégié, comme une clé d'API serveur ou un jeton d'administration, et ne doit jamais quitter votre backend.

    Le tableau suivant aide à trancher pour les cas courants.

    Type de cléExemplePeut-elle être dans le front-end ?
    Clé publiableClé publishable Stripe, config FirebaseOui, elle est prévue pour être publique
    Clé restreinte par appClé Google Maps restreinte par bundle IDOui, si elle est restreinte chez le fournisseur
    Clé d'API serveurClé secrète d'un service tiersNon, jamais
    Clé privée ou secretClé privée de signature, secret OAuthNon, jamais

    La question à se poser pour chaque clé est simple : si cette valeur devient publique, quelqu'un peut-il en abuser ? Si la réponse est oui, la clé est secrète et n'a rien à faire dans le front-end. Si la clé est de toute façon publique, le travail consiste à la restreindre, pas à la cacher.

    Les dangers concrets d'une clé exposée

    Une clé exposée n'est pas un risque théorique ; elle entraîne des conséquences mesurables. La plus fréquente est l'abus de quota et la facture qui explose : une clé de cartographie ou d'un service payant, laissée sans restriction, peut être utilisée par des tiers jusqu'à générer des milliers d'euros de coûts sur votre compte.

    Au-delà du coût, une clé secrète exposée peut ouvrir l'accès à des données, permettre d'usurper des comptes, ou transformer votre backend en proxy gratuit pour un attaquant. Une clé d'un service tiers peut aussi servir à agir en votre nom sur ce service. Le dénominateur commun est que l'attaquant hérite des privilèges de la clé, et ces privilèges sont souvent bien plus larges que ce dont l'app avait besoin.

    Comment corriger : déplacer les secrets vers un backend

    La solution de fond pour une clé secrète est de ne jamais la mettre dans l'app. À la place, placez-la sur un backend que vous contrôlez, et faites appeler ce backend par l'app. L'app envoie une requête à votre serveur, le serveur ajoute la clé secrète et relaie l'appel au service tiers. La clé reste ainsi hors de portée de l'utilisateur.

    Ce modèle, souvent appelé backend-for-frontend ou proxy, a un autre avantage : il vous donne un point de contrôle. Vous pouvez y appliquer une authentification, limiter les débits, journaliser les usages et révoquer un accès sans republier l'app. Pour les opérations sensibles, c'est la seule approche réellement sûre, car elle place le secret dans le seul endroit que l'utilisateur ne contrôle pas.

    Comment restreindre les clés qui doivent rester côté client

    Certaines clés, comme une clé Google Maps, doivent vivre dans l'app. Pour celles-là, l'objectif n'est pas de les cacher mais de les restreindre chez le fournisseur. Google recommande fortement de restreindre toutes les clés : par application (identifiant de bundle iOS, ou nom de package et empreinte SHA-1 sous Android), par API autorisée, et par quota, selon ses bonnes pratiques de sécurité.

    Il faut être honnête sur la portée de ces restrictions. Une restriction par identifiant d'app est une vérification ajoutée aux requêtes, pas une preuve cryptographique, et un appel direct à l'API avec un en-tête falsifié peut parfois passer. Elle reste néanmoins une barrière utile, surtout combinée à des restrictions d'API et à des quotas qui plafonnent les dégâts. Restreindre une clé publique ne la rend pas secrète ; cela limite ce qu'un tiers peut en faire.

    Secrets et CI/CD : éviter les fuites dans le pipeline

    Beaucoup de fuites ne viennent pas de l'app elle-même, mais du pipeline. Un fichier .env commité dans Git, une clé écrite en dur dans un script Fastlane, ou un secret injecté dans le bundle par un build EAS mal configuré : chacun expose la clé aussi sûrement que si vous l'aviez publiée. L'historique Git est particulièrement traître, car une clé retirée dans un commit reste présente dans l'historique.

    La bonne pratique est de garder les secrets dans le coffre de secrets de votre système d'intégration continue, et de ne les injecter qu'au bon endroit. Un secret serveur ne doit jamais atteindre le bundle client ; une clé publique restreinte, oui. Vérifiez aussi votre .gitignore, et si une clé a déjà été commitée, révoquez-la, car la retirer de l'historique ne suffit pas à la considérer comme sûre.

    Checklist de remédiation

    Si vous découvrez une clé exposée, agissez dans l'ordre, de l'urgence immédiate à la prévention continue. Le tableau ci-dessous donne une marche à suivre claire.

    ÉtapeActionPriorité
    1Révoquer et régénérer toute clé secrète exposéeImmédiate
    2Déplacer les appels sensibles vers un backend proxyHaute
    3Restreindre les clés publiques (bundle ID, API, quotas)Haute
    4Retirer les secrets du bundle et de l'historique GitHaute
    5Utiliser des jetons éphémères émis par le serveurMoyenne
    6Scanner le build avant chaque publicationContinue

    La première ligne est la plus urgente : une clé secrète exposée doit être révoquée et régénérée sans attendre, car tant qu'elle est valide, elle reste exploitable. Les étapes suivantes empêchent la situation de se reproduire.

    Détecter les secrets avant la publication

    La meilleure défense est de repérer une clé exposée avant qu'elle n'atteigne les magasins. Il est facile de laisser passer une clé oubliée dans un module natif, un fichier de configuration ou une dépendance, surtout quand plusieurs personnes touchent au projet. Une revue manuelle ne voit pas tout.

    Un scanner comme PTKD.com analyse votre .ipa ou votre .apk et renvoie des résultats classés par gravité et alignés sur l'OWASP MASVS, ce qui inclut les secrets embarqués, le stockage non sécurisé et les mauvaises configurations réseau. Il faut être clair sur ses limites : un scanner ne remplace pas le déplacement de vos secrets vers un backend, ni un audit manuel pour une app à haut risque, et il ne peut pas deviner si une clé publique est correctement restreinte chez le fournisseur. Ce qu'il fait, c'est signaler les secrets évidents avant qu'ils ne fuient.

    Ce qu'il faut retenir

    • Une clé dans le front-end n'est jamais secrète : le client est toujours inspectable.
    • Un fichier .env ne protège rien dans une app mobile ; les variables EXPO_PUBLIC_ sont intégrées en clair.
    • Les clés secrètes doivent vivre sur un backend proxy, jamais dans l'app.
    • Les clés forcément publiques doivent être restreintes par identifiant d'app, API et quota chez le fournisseur.
    • En cas de fuite, révoquez immédiatement, puis scannez chaque build avec PTKD.com avant publication.
    • #clés API
    • #react native
    • #expo
    • #sécurité mobile
    • #OWASP MASVS

    Frequently asked questions

    Une clé API dans une app React Native est-elle sécurisée ?
    Non. Le code d'une app React Native est livré sur l'appareil de l'utilisateur, et les clés qu'il contient peuvent être extraites en décompilant l'app, en lisant le bundle JavaScript ou en interceptant le trafic. Une clé secrète ne doit donc jamais s'y trouver ; elle doit vivre sur un backend que vous contrôlez.
    Le fichier .env protège-t-il ma clé dans une app mobile ?
    Non. Sur un serveur, un .env garde les valeurs hors du code, mais dans une app mobile, les variables sont intégrées en clair dans le bundle au moment du build. La documentation d'Expo précise de ne jamais mettre de secret dans une variable EXPO_PUBLIC_. Le .env organise vos secrets en développement, mais ne les cache pas dans l'app distribuée.
    Quelle est la différence entre une clé publique et une clé secrète ?
    Une clé publique est conçue pour être visible, comme une clé publishable Stripe ou une configuration Firebase, et peut vivre dans le client. Une clé secrète donne un accès privilégié, comme une clé d'API serveur ou un jeton admin, et doit rester sur votre backend. La question décisive : si la valeur devient publique, peut-on en abuser ?
    Comment cacher une clé API dans une app mobile ?
    On ne peut pas vraiment la cacher : tout ce qui est livré dans l'app est extractible. L'obfuscation ne fait que ralentir un attaquant. La vraie solution est de déplacer les clés secrètes vers un backend, et de restreindre chez le fournisseur les clés qui doivent rester côté client, plutôt que d'essayer de les dissimuler.
    Ma clé Google Maps a fuité, que faire ?
    Restreignez-la immédiatement par identifiant de bundle iOS ou nom de package Android, limitez-la aux seules API nécessaires, et fixez des quotas pour plafonner les coûts. Si l'abus continue, régénérez la clé et remplacez-la dans une nouvelle version de l'app. Ces restrictions ne rendent pas la clé secrète, mais limitent ce qu'un tiers peut en faire.
    Comment détecter les secrets exposés avant de publier ?
    Analysez le build avant chaque publication. Un scanner comme PTKD.com (https://ptkd.com) inspecte votre .ipa ou .apk et signale les secrets embarqués, le stockage non sécurisé et les configurations réseau risquées, alignés sur l'OWASP MASVS. Il ne remplace pas le déplacement des secrets vers un backend, mais il repère les clés oubliées avant qu'elles ne fuient.

    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