Rencontre du 3ème tiers ...
Par Exocet le mardi, 11 mai 2010, 13:01 - Il était une fois... - Lien permanent
Voilà un petit retour d'expérience sur les audits d'applications 3-tiers.
Pour commencer, mettons nous d'accord sur les termes.
- Architecture 2-tiers:
Un client dialogue avec un serveur. Dans la plupart des cas, il s'agit d’un client lourd qui se connecte à une base de données.
- Architecture 3-tiers:
Un client parle à un serveur qui parle à un autre serveur. Dans la vraie vie il s'agit d'un client qui dialogue avec un serveur applicatif qui lui même dialogue avec une base de données.
Voilà pour une terminologie approximative!
Pour la plupart des informaticiens, les vulnérabilités d'une application en architecture deux tiers sont assez évidentes.
Voici par exemple quelques problèmes rencontrés fréquemment sur du 2-tiers:
- Les secrets sont souvent stockés côté client dans un fichier de configuration, dans un script ou codés en dur dans le binaire ou en mémoire.
- Le client via son IHM, se connecte directement à la base de données pour envoyer des actions. Il est facile d'intercepter et de modifier les requêtes SQL envoyées à la base avec des outils comme EchoMirage.
- L'utilisateur utilise un compte de base de données pour lancer l'application. Il est alors possible de se connecter directement à la base avec son client SQL. Cela pourrait ne poser aucun problème (ou presque ^^) s'il était facile pour les DBAs ou aux équipes de support de gérer finement la ségrégation verticale/horizontale de centaines ou de milliers utilisateurs directement en base. Les utilisateurs ont donc accès à l'ensemble des données contenus dans la base aussi bien en lecture qu'en écriture... Génial.
- L'application utilise un unique compte de base pour tous les clients. Ainsi au lancement de l'application, le client se connecte à la base avec un compte générique pour vérifier les identifiants applicatifs stockés en base. Il est possible de faire du SQL tampering pendant l'authentification applicative et d'accéder à la base pour récupérer tous les comptes applicatifs, ou pour valider son authentification.
- La plupart des permissions applicatives sont gérées côté client, Eureka et les fenêtres se dégrisent

Voilà, une fois que l'on a réalisé tout ça, et qu'on a pardonné aux architectes des années Mitnick d'avoir déguisé un client SQL en une application de Trading (par exemple), on peut envisager le passage aux architectures 3-tiers pour les futures applications.
On utilise alors le tiers applicatif supplémentaire pour contrôler les accès clients aux données, et on y gère aussi les secrets d'accès à la base. Tout est parfait.
Le billet aurait même pu s'arrêter là, (ou même n'avoir jamais existé), mais cela voudrait dire que TOUS les développeurs et architectes de profession savent pourquoi ils sont passés d'une architecture 2-tiers à du 3-tiers... (10 minutes d'auto flagellation pour tous ceux qui ont cru cela possible).
En effet, la sécurité n'est encore bien souvent qu'un mirage dans l'esprit des développeurs, et cela est d'autant plus frappant (déprimant) lorsqu'on s'aperçoit que certaines applications 3-tiers ne sont pas plus sécurisées que des 2-tiers voire réimplémentent les mêmes vulnérabilités.
Pour appuyer mes dires (et pour se marrer un peu aussi =)), notre "consultant proxy" Melvin Kitnick nous a préparé une petite séléction de vulnérabilités qu'il a croisé dans des applications 3-tiers ces dernières années (tous secteurs confondus):
Les classiques du 3-tiers:
1. Les identifiants de base de données sont inutiles MAIS disponibles côté client. On les retrouve dans un fichier de configuration, dans le binaire ou dans la mémoire après le lancement du client (Si si je vous assure c'est vrai et relativement fréquent).
2. Les contrôles des permissions sont effectués uniquement côté client (à la mode 2-tiers) et non sur le tiers serveur applicatif. En bref, un attaquant peut accéder à des fonctionnalités ne correspondant pas à son profil utilisateur, par exemple en modifiant le client, ou plus simplement, en d'interceptant et en modifiant les données échangées avec le serveur.
Il est souvent possible de modifier son profil à la réception ou bien de modifier des actions à l'envoi, Enfin, il est parfois possible en utilisant un utilitaire de kiddies de réactiver les boutons de fonctionnalités auxquelles votre profil utilisateur n'a pas accès. (Oui aussi sur du 3-tiers ;-))
Les moins classiques mais croisés plusieurs fois:
3. Dans la même famille que la précédente, le mot de passe est vérifié côté client. Chez nous, le client est roi, et c'est lui qui décide si son mot de passe est bon. Par la même occasion il est alors possible de récupérer les hashs et mots de passe de n'importe quel utilisateur.
4. Il n'est pas rare que certaines applications soient très mal packagées. Le client lourd distribué aux utilisateurs contient les classes compilées et les fichiers de configuration du serveur... et donc les secrets qu'il embarque.
Le cas particulier
5. Une équipe de développeurs pleine de bon sens se dit Tain', les gars, c’est trop la honte d'avoir une appli 2-tiers ! Même mes enfants se foutent de ma gueule, leur prof d'électrotechnique leur a dit que ça n'existait plus le 2-tiers. Allez on fait péter les technos applicatives et on passe en 3-tiers.
Héhé, c'est super bien comme initiative, mais ça prend du temps de refaire une application... des mois voire des années. Et pendant ce temps, l'application est un chantier digne du désamiantage des Twin Towers ou de Jussieu… Pendant ce chantier, certaines fonctionnalités sont donc en 2-tiers (accès direct à la base) et d'autres en trois tiers...
Le résultat est une application "best of both worlds", pwnable en 2 minutes malgré l'archi 3-tiers. Tant qu'il restera une fonctionnalité ayant un comportement 2-tiers, on ne profitera pas de l'avantage sécurité de l'archi 3-tiers. Logique non? Ben pas pour tout le monde...
La palme
6. Le client envoie des requêtes SQL au serveur applicatif, qui les exécutent sans modification sur le serveur de base de données. 1 minute de silence (profitez en pour pwner la base)...
Conclusion
Que penser de ça ? Comment en arrive t-on là, en ayant pris la bonne décision d'archi dès le début ? S’agit-il d'un simple manque de formation, de fainéantise, de temps, ou d'un désintéressement pour la sécurité ?
La réponse est sûrement un mélange de tout ça. Sans oublier l'effet marketing du 3-tiers à la mode dans le bancaire, qui fait croire que le simple choix de cette architecture sécurise l'application... c'est comme croire qu'un site Web est sécurisé grâce au SSL. C'est bien mais c'est pas suffisant ...
Enfin bref, je ne suis pas là pour tirer sur l'ambulance, mais juste pour rappeler qu'un des buts d'une archi 3-tiers et d'éviter ces désagrément:
- Le client n'accède pas directement à la base, il envoie ses demandes d'accès aux données au serveur applicatif, qui se chargera après autorisation, d'effectuer les accès base nécessaires.
- Le serveur applicatif vérifie toujours les permissions des clients avant d'exécuter leurs actions.
- Le serveur applicatif filtre les données envoyées par le client avant de les réutiliser.
- Le client n'embarque pas de secrets compromettant pour l'application (mot de passe de base, clefs, "intelligence" applicative).
C'est très synthétique et vulgarisé, mais s’il y a des développeurs qui lisent ce billet, demandez-vous si vous respectez les 4 derniers points.
Si celà n'est pas le cas, vous savez ce qu'il vous reste à faire (ou pas, comme dirait Hurukan
).
Si oui, "BRAVO !" vous méritez une augmentation et vous pouvez maintenant penser à chiffrer les flux entre vos tiers. (Mouhahaha)
.
Commentaires
Bravo, c'est très vrai :)
Plein de clients sont persuadés de résoudre tous ces problèmes uniquement en "mettant du SSL" entre le client et le serveur appli... C'est bien connu : le chiffrement, c'est comme les firewalls, ça règle tous les problèmes !
Tu as aussi les architectures "Multi-N-Tiers" (mnt, pour massivement N tiers ? :)) dans lesquelles un client va taper plusieurs infrastructures différentes, au sein d'un même service, chacune d'entre elles en N-Tiers.
Typiquement, un service de commerce en ligne qui renvoie le client vers un service de paiement. La communication des données entre les entités est, du point du pentester, souvent très intéressante ;)
Ah les N tiers. Ca me fait penser à des archis avec du Web service à gogo.
Mais sinon je préfère les quatre quarts ;-)
Oui effectivement le MNT a aussi son charme et l'exemple 3tiers de ce billet peut s'appliquer à plusieurs autres types d'archi "élaborées".
On revient alors à la même constatation, on passe souvent d'un choix d'archi offrant de bonnes perspectives de sécurité, à une implementation qui n'exploite pas ces perspectives et réouvre des portes aux attaquants.
Les archis N-tiers (N>3), ça ne change de manière générale rien au travail du pentester :
- si les données utilisateurs ne sont pas filtrées, c'est pas en rajoutant des tiers que ça va s'améliorer.
- si on a arrive à prendre la main sur le serveur frontal, comme c'est généralement celui qui gère l'authentification, c'est déjà tout gagné : on peut usurper n'importe qu'elle identité.
Je suis même persuadé que les hackers ne se rendent pas compte de la complexité des architectures applicatives. À votre avis, il y a combien de tiers dans une application de banque en ligne ? (on imagine que le site a de beaux XSS facilements exploitables par un amateur, ce qui n'est pas du tout improbable) À la louche (j'ai des taupes), je voterais pour 6.
Avant de multiplier les tiers, mieux vaut commencer par installer un WAF.
Un WAF?
on parle bien de la boite qui clignote et "qui fait joli" dans la baie, que les décideurs se sont fait vendre à prix d'or par un avant vente et qu'un pentester contourne en 2s via une syntaxe que le boitier ne gère pas? (et qui se fait installer/configurer par un ingé sécurité prestataire ne connaissant pas ce que sont (ou la différence entre) un XSS et un CSRF )
Pour repartir sur une note plus positive, un WAF va quand même permettre de ralentir/arrêter certaines attaques et potentiellement décourager l'attaquant, mais ce n'est certainement pas le saint Graal des applications web
A Shmurtz :
Pour ton deuxième "-", ce que tu dis est vrai. Cependant, avoir la main sur le frontal en N-tiers, c'est normalement plus dur que d'avoir la main sur ton propre poste quand tu attaques du 2-tiers.
Je suis d'accord, multiplier les tiers ne sert à rien. De base, il faut savoir pourquoi on ajoute au moins un tiers au lieu de taper directement la base de données. Les applications dont parle Exocet dans son article sont probablement des applis internes, certainement dans le milieu de la finance, je suppose.
En effet, j'ai oublié de preciser que ce retour d'expérience est basé sur des tests d'appli internes.
Je suis daccord avec Schmurtz, qu'au dela de 3tiers, ce n'est pas l'ajout de tiers qui va véritablement changer qqchose au pentest. En revanche le passage du 2 au 3 tiers ou plus, doit permettre de changer grandement le niveau de sécurité de l'appli et pourtant ce n'est pas souvent le cas. C'est là ou je voulais en venir.;-)
6 tiers!!! C'est pour ça que les sites bancaires sont si lents et qu'avec 3 connexions en parallèle on fait du déni de service ;-)
Sinon difficile de faire une moyenne du nombre de tiers. C'est quand même super dépendant du type d'application et du client...
Par exemple, faire une appli de trading en 6 tiers, bonjour les perfs, pas la peine d'y compter quand la milliseconde compte ;-)
Pour autant sur des sites de services ça peut monter rapidement avec des Web services par exemple qui peuvent taper des applis / bases différentes.
De toute façon pour des tests externes, on ne tape souvent qu'un tiers ;-)
Enfin selon moi, un firewall applicatif ne permet pas de se protéger de toutes les attaques applicatives et celà n'est pas la solution miracle, on retrouve souvent des syntaxes qui peuvent les contourner.
Maintenant on est d'accord, ça augmente la difficulté d'exploitation des failles et ça fait chier le pentester.
@Un (autre) pentester, t'a oublié aussi une autre idée à la con du même genre qui m'énerve : "Le GET y parait que c'est mal, moi jfais du POST c'est plus secure, comme ça je peux tout cacher au client..." ou pas ...
Le principal problème des WAF c'est qu'a moins qu'il soit installés à la suite d'un pentest ça fait flipper n'importe quel client! Mon dieu, les dev vont devoir communiquer avec le mec de l'équipe réseau qui gère le boitier !
Ce qui donne comme résultat une installation du boitier en mode IDS avec une pov' base de signature (snort ?...) qu'on sait tous contourner depuis des années. Pire, certains clients s'en cognent complètement et doivent juste avoir un reverse proxy (PCI toussa toussa...), c'est pas si cher que ça finalement une belle boite Cover Your Ass à seulement 50k qui termine les connexion SSL et qui fait du DLP sur toutes les requêtes en sortie.
A mon sens, bien configuré (ex: exp régulière par paramètre/page) c'est pas trop contournable. Pour les applis web vraiment mal branlées, on peut même aller jusqu'à fixer les paramètres (champs hidden ou n'importe) lors de l'envoie par le serveur afin d'éviter leur modification en retour par le client. Un autre truc qui m'a scié aussi, certain boitiers gèrent même le CSRF ! Franchement, ça m'a étonné mais techniquement c'est au point et répond à quasiment tout ce qu'on remonte lors des pentests, même sur les web services.
Donc ouais comme dit Mat, tout dépend de qui l'installe! Mais surtout de comment veut se faire chier le client ou pas! Tant que le client s'est pas fait poutré par un pentest et qu'il a pas du rouge dans ses tableaux de bords de merde il s'en bat! on tourne en rond et on retombe sur les mêmes problèmes qui font que l'appli derrière est pourrie. C'est du pur niveau 8 mais malheureusement, aucune boite n'est capable de le gérer et encore moins la "communication entre ses différents composants"! Peut importe le nombre de tiers finalement..