Introduction
Tous les services numériques du quotidien sont exposés à des menaces cyber de plus en plus sophistiquées. Certaines d'entre elles restent limitées grâce aux solutions de défense mises en place par les entreprises, tandis que d'autres peuvent s'avérer particulièrement dévastatrices.
Nous avons récemment audité une banque en ligne qui détient beaucoup d'informations sensibles (Identité, Cartes bancaires, Relevés, RIB, etc.). Le résultat de notre expertise a mis en évidence plusieurs vulnérabilités critiques au sein de leur application web, pouvant mener aux données précieuses de l'entreprise.
Pour des raisons évidentes de confidentialité, nous remplacerons le nom de la banque et les URLs par des éléments fictifs. Nous utiliserons à la place le nom 9bank.
Scope
Nous avons concentré nos tests sur l'application web, qui constitue l'interface principale mise à disposition des clients de 9bank. Pour explorer le plus largement possible les vulnérabilités, la banque nous a fourni un jeu d'identifiants valides (adresse e‑mail et mot de passe) afin que nous puissions nous connecter en tant qu'utilisateur légitime et agir comme un client test.
Par ailleurs, le client nous a expressément autorisés à élargir le périmètre d'audit à tous les sous-domaines de 9bank. Cette autorisation inclut la découverte de tous les sous‑domaines non communiqués au préalable ainsi que leur évaluation complète. Ainsi, nous pourrons couvrir l'ensemble des URL et points d'entrée potentiels, même ceux qui ne figuraient pas dans la description initiale du périmètre.
Recherche d'identifiants compromis
Avec l'accord explicite de 9bank, nous avons mené une recherche ciblée d'identifiants sur le Darknet afin de vérifier si des comptes de l'application web ont été compromis.
À noter que nous proposons un service de veille continue du Darknet. Ce service assure un monitoring 24 / 7 des sources clandestines, génère des alertes en temps réel dès la détection de nouveaux identifiants appartenant à l'entreprise et fournit chaque mois un rapport de tendance ainsi que des recommandations de mitigation (MFA, réinitialisation de mots de passe, etc.). Cette offre permet à toute organisation d'être immédiatement alertée en cas de compromission de ses données d'authentification, afin de réagir avant toute exploitation malveillante. Un prochain article présentera en détail les atouts et le fonctionnement de ce service.
Au cours de cette phase de recherche, une dizaine d'identifiants valides compromis ont été identifiés, permettant à nos équipes d'obtenir un premier accès utilisateur. Pour des questions de respect de la vie privée nous avons juste informé notre client de cette information et continué l'audit avec des identifiants de test.
Vulnérabilités identifiées
SQL Injection critique (dump complet BDD)
Dès le début de nos tests, quelque chose a attiré notre attention
: En rejouant la requête GET /getRib avec des valeurs
volontairement incorrectes, le paramètre client_id a
provoqué une erreur SQL visible côté client. Le genre d'erreur qui
fait tilt immédiatement :
L'utilisation d'outils comme sqlmap ou ghauri nous ont permis de vérifier si cette vulnérabilité potentielle était exploitable ou non.
La réponse est oui ! Nous avons pu récupérer la base de données de 9bank, contenant l'ensemble des clients, leurs transactions, leurs coordonnées bancaires, etc. et ce sans être authentifié.
Par ailleurs, La requête GET /getReleveOperation est
également vulnérable.
En tombant sur cette injection SQL, on a eu un petit sourire. Pas moqueur... plutôt celui qu'on a quand on croise un vieux fantôme qu'on pensait presque disparu. En 2025, les SQLi ne font plus vraiment partie du paysage courant : on en voit beaucoup moins, les frameworks modernes ont fait leur travail. Mais parfois, au détour d'un module oublié, d'un bout de code qui a survécu à trois refontes… elles réapparaissent. Et quand c'est le cas, c'est toujours le rappel discret que les failles "à l'ancienne" ne meurent jamais vraiment, elles se cachent juste mieux.
Cette SQLi était déjà sérieuse, mais la suite l'était encore plus... En analysant les mécanismes de sécurité autour de l'authentification, nous avons mis en évidence un contournement possible du 2FA.
Contournement du 2FA (OTP Bypass)
Certaines fonctionnalités principales ne pouvaient réellement être testées dû aux limitations de notre compte client. Lorsque nous tentions des actions comme faire un virement, un code envoyé par SMS nous était demandé. Cependant, le numéro affiché ne nous appartenait pas, ce qui rendait impossible la récupération du code.
Néanmoins, en analysant le fonctionnement de l'OTP, un détail nous a mis la puce à l'oreille : rien ne semblait prouver que le code SMS était réellement validé côté backend. Le mécanisme paraissait surtout géré par le navigateur. Par curiosité et par prudence, nous avons vérifié ce point dans les requêtes API. Et la validation du code ne semble jamais vraiment contrôlée par le serveur, ce qui permet de réaliser l'action sensible sans validation de l'OTP.
Nous avons donc fouillé dans le code JavaScript chargé par le
navigateur, à la recherche d'indices. Une simple recherche de
"/verify-otp" nous a menés sur une portion de code
dédiée à la vérification du SMS :
C'est là que tout s'éclaire : Le code vérifie d'abord une variable nommée isOtpActivated.
- Si isOtpActivated = true, la vérification SMS est réellement déclenchée.
- Si isOtpActivated = false, le code saute complètement l'étape 2FA et passe directement à l'action (ex. : ajout de bénéficiaire, virement…).
Autrement dit : tout repose sur une variable booléenne fixée au chargement de la page. Aucune garantie serveur, aucune validation obligatoire côté backend.
Quelques minutes suffisent pour identifier la requête concernée :
/settings/web.
Nous avons alors intercepté la réponse de
/settings/web à l'aide de l'outil
Caido, modifié la valeur de
isOtpActivated pour la passer à
false, puis laissé le navigateur exécuter le
JavaScript normalement.
Résultat :
- aucun SMS demandé,
- aucune vérification effectuée,
- et pourtant, toutes les actions sensibles sont possibles.
Nous avons pu :
- ajouter un nouveau bénéficiaire,
- puis réaliser un virement vers ce compte test.
Et tout cela… avec uniquement une paire email/mot de passe, sans jamais avoir accès au 2FA légitime.
Chiffrement client-side : une barrière facilement contournable
Lors de la lecture du contenu de certaines requêtes HTTP, on remarque la présence d'une chaîne chiffrée dans l'URL. On imagine facilement que le but est d'empêcher l'utilisateur de lire ou modifier les données transmises.
Nous décidons alors de fouiller un peu le code source Javascript de l'application pour tenter d'y trouver la ligne de code qui permet le chiffrement. Après quelques recherches par mot-clés, on trouve un morceau de code plutôt intéressant :
Il ne nous reste plus qu'à écrire un petit script pour déchiffrer et chiffrer nos chaînes de caractères mystérieuses. Au vu de la faible complexité du code, un LLM nous a permis de générer un script fonctionnel en quelques minutes, ce qui a accéléré la phase d'analyse.
Résultat : Une fois le mécanisme de chiffrement compris et reproduit, nous avons pu déchiffrer sans difficulté l'ensemble des chaînes présentes dans les requêtes HTTP.
Comme le chiffrement est entièrement réalisé côté client et que la clé est accessible dans le code JavaScript, il devient alors possible aisément d'intercepter, modifier, rejouer toutes les requêtes contenant ces chaînes chiffrées.
Concrètement, via Caido ou Burp, on peut donc facilement :
- intercepter chaque requête chiffrée,
- la déchiffrer automatiquement,
- modifier n'importe quelle donnée interne,
- la rechiffrer,
- puis la renvoyer vers le serveur,
le tout en temps réel. Il suffit pour cela de développer un petit plugin, ce qui permettrait d'automatiser entièrement le processus.
IDOR sur API AWS Gateway (RIB, relevés, données clients)
Lors de l'utilisation de certaines fonctionnalités de base, comme la récupération du RIB ou ou l'accès au relevé d'opérations, nous avons observé que l'application effectuait des appels API vers un service AWS API Gateway.
Nous nous sommes d'abord concentrés sur la récupération du RIB. Comme nous pouvons le voir ci-dessus, les paramètres de la requête sont très simples :
- client_id : on suppose l'identifiant unique du client ;
- store_on_s3 : on suppose la sauvegarde du fichier ou de la requête sur s3 ;
- env : on suppose l'environnement de l'application (staging ou prod).
Le premier paramètre à tester est naturellement client_id. Et le résultat est sans équivoque : en modifiant sa valeur, il est possible d'obtenir le RIB d'un autre utilisateur, ce qui constitue une vulnérabilité critique.
Résultat : nous avons ainsi pu extraire les informations bancaires d'un compte tiers. Avec des outils d'automatisation, il serait très simple de reproduire cette attaque massivement pour récupérer le RIB de l'ensemble des comptes clients.
Conclusion
L'audit a révélé plusieurs vulnérabilités critiques ayant un impact direct sur la confidentialité, l'intégrité et la sécurité des données clients. Parmi les failles identifiées :
- IDOR sur API AWS Gateway, permettant d'accéder aux RIB, relevés et données d'autres utilisateurs ;
- Chiffrement client-side facilement contournable, rendant possible la lecture, modification et replay de requêtes sensibles ;
- Contournement du 2FA (OTP Bypass), annulant une protection pourtant essentielle lors d'actions critiques comme la réalisation de virements vers des comptes bénéficiaires non enregistrés ;
- SQL Injection critique, ouvrant la voie à l'extraction complète des bases de données, sans authentification.
Ces failles, permettent un scénario d'attaque complet : accès aux données, modification d'opérations, escalade de privilèges et actions frauduleuses.
Au-delà de ces vulnérabilités, cet audit rappelle l'importance de réaliser régulièrement des tests d'intrusion. Les applications évoluent, les équipes changent, de nouveaux modules apparaissent… et chaque modification peut introduire des failles. Chez HDW Sec, nous accompagnons quotidiennement des entreprises dans ces démarches : identification des risques, tests d'intrusion complets, validation des correctifs et suivi dans la durée.
👉 Nous recommandons fortement de planifier des pentests réguliers, afin de détecter en amont les failles critiques et maintenir un niveau de sécurité conforme aux exigences actuelles.