Contactez-nous

Cartographier l'architecture de l'application

Comment comprendre l'architecture d'une application web et identifier les différents composants (serveur web, base de données, services tiers, etc.) et les composants réseau (proxy inverse, pare-feu, CDN, etc.).

ID
WSTG-INFO-10

Résumé

Afin de tester efficacement une application et de pouvoir fournir des recommandations significatives sur la manière de résoudre les problèmes identifiés, il est important de comprendre ce que l'on teste réellement. De plus, il pourrait être utile de déterminer si des composants spécifiques doivent être considérés comme hors de portée pour les tests.

Les applications web modernes peuvent varier considérablement en complexité, d'un simple script s'exécutant sur un seul serveur à une application très complexe répartie sur des dizaines de systèmes, de langages et de composants différents. Il peut également y avoir des composants supplémentaires au niveau du réseau, tels que des pare-feu ou des systèmes de protection contre les intrusions, qui peuvent avoir un impact significatif sur les tests.

Objectifs du test

  • Comprendre l'architecture de l'application et les technologies utilisées.

Comment tester

Lors de tests à partir d'une perspective de boîte noire, il est important d'essayer de construire une image claire du fonctionnement de l'application et des technologies et composants en place. Dans certains cas, il est possible de tester des composants spécifiques tels qu'un pare-feu d'application web, tandis que d'autres composants peuvent être identifiés en inspectant le comportement de l'application.

Les sections ci-dessous fournissent un aperçu de haut niveau des composants architecturaux courants, ainsi que des détails sur la façon dont ils peuvent être identifiés.

Composants de l'application

Serveur Web

Les applications simples peuvent s'exécuter sur un seul serveur, qui peut être identifié en utilisant les étapes décrites dans la section Fingerprint Web Server du guide.

Platform-as-a-Service (PaaS)

Dans un modèle Platform-as-a-Service (PaaS), le serveur web et l'infrastructure sous-jacente sont gérés par le fournisseur de services, et le client n'est responsable que de l'application qui y est déployée. Du point de vue des tests, il y a deux différences principales :

  • Le propriétaire de l'application n'a pas accès à l'infrastructure sous-jacente, ce qui signifie qu'il ne pourra pas directement remédier aux problèmes.
  • Les tests d'infrastructure sont susceptibles d'être hors de portée pour tout engagement.

Dans certains cas, il est possible d'identifier l'utilisation de PaaS, car l'application peut utiliser un nom de domaine spécifique (par exemple, les applications déployées sur Azure App Services auront un domaine `*.azurewebsites.net` - bien qu'elles puissent également utiliser des domaines personnalisés). Dans d'autres cas, il est difficile de déterminer si PaaS est utilisé.

Serverless

Dans un modèle Serverless, les développeurs fournissent du code qui est directement exécuté sur une plateforme d'hébergement en tant que fonctions individuelles, plutôt que d'exécuter une application web traditionnelle plus grande déployée dans une racine web. Cela le rend bien adapté à l'architecture basée sur les microservices. Comme pour un environnement PaaS, les tests d'infrastructure sont susceptibles d'être hors de portée.

Dans certains cas, l'utilisation de code Serverless peut être indiquée par la présence d'en-têtes HTTP spécifiques. Par exemple, les fonctions AWS Lambda renvoient généralement les en-têtes suivants :

X-Amz-Invocation-Type
X-Amz-Log-Type
X-Amz-Client-Context

Les fonctions Azure sont moins évidentes. Elles renvoient généralement l'en-tête `Server: Kestrel` - mais cela seul ne suffit pas pour déterminer qu'il s'agit d'une fonction Azure App, car il pourrait s'agir d'un autre code s'exécutant sur Kestrel.

Microservices

Dans une architecture basée sur les microservices, l'API de l'application est composée de plusieurs services discrets, au lieu d'être exécutée en tant qu'application monolithique. Les services eux-mêmes s'exécutent souvent dans des conteneurs (généralement avec Kubernetes) et peuvent utiliser une variété de systèmes d'exploitation et de langages différents. Bien qu'ils soient généralement derrière une seule passerelle API et un seul domaine, l'utilisation de plusieurs langages (souvent indiquée dans des messages d'erreur détaillés) peut suggérer que des microservices sont utilisés.

Stockage statique

De nombreuses applications stockent du contenu statique sur des plateformes de stockage dédiées, plutôt que de l'héberger directement sur le serveur web principal. Les deux plateformes les plus courantes sont les buckets S3 d'Amazon et les comptes de stockage d'Azure, et peuvent être facilement identifiées par les noms de domaine :

  • `BUCKET.s3.amazonaws.com` ou `s3.REGION.amazonaws.com/BUCKET` pour les buckets Amazon S3
  • `ACCOUNT.blob.core.windows.net` pour les comptes de stockage Azure

Ces comptes de stockage peuvent souvent exposer des fichiers sensibles, comme indiqué dans la section Testing Cloud Storage Guide.

Base de données

La plupart des applications web non triviales utilisent une sorte de base de données pour stocker du contenu dynamique. Dans certains cas, il est possible de déterminer la base de données. Cela peut souvent être fait en :

  • Scannant les ports du serveur et en recherchant les ports ouverts associés à des bases de données spécifiques
  • Déclenchant des messages d'erreur liés à SQL (ou NoSQL) (ou en trouvant des erreurs existantes à partir d'un moteur de recherche

Lorsqu'il n'est pas possible de déterminer de manière concluante la base de données, le testeur peut souvent faire une estimation éclairée basée sur d'autres aspects de l'application :

  • Windows, IIS et ASP.NET utilisent souvent Microsoft SQL Server
  • Les systèmes embarqués utilisent souvent SQLite
  • PHP utilise souvent MySQL ou PostgreSQL
  • APEX utilise souvent Oracle

Ce ne sont pas des règles strictes, mais peuvent certainement vous donner un point de départ raisonnable si aucune meilleure information n'est disponible.

Authentification

La plupart des applications ont une authentification utilisateur. Il existe plusieurs backends d'authentification qui peuvent être utilisés, tels que :

  • Configuration du serveur web (y compris les fichiers `.htaccess`) ou codage en dur des mots de passe dans les scripts
    • Se présente généralement sous la forme d'une authentification HTTP Basic, indiquée par une fenêtre contextuelle dans le navigateur et un en-tête HTTP `WWW-Authenticate: Basic`
  • Comptes d'utilisateurs locaux dans une base de données
    • Généralement intégré dans un formulaire ou un point de terminaison API sur l'application
  • Une source d'authentification centrale existante telle qu'Active Directory ou un serveur LDAP
    • Peut utiliser l'authentification NTLM, indiquée par un en-tête HTTP `WWW-Authenticate: NTLM`
    • Peut être intégré dans l'application web dans un formulaire
    • Peut exiger que le nom d'utilisateur soit saisi au format "DOMAINE\nom d'utilisateur", ou peut donner une liste déroulante des domaines disponibles
  • Single Sign-On (SSO) avec un fournisseur interne ou externe
    • Utilise généralement OAuth, OpenID Connect ou SAML

Les applications peuvent fournir plusieurs options à l'utilisateur pour s'authentifier (comme l'enregistrement d'un compte local ou l'utilisation de son compte Facebook existant), et peuvent utiliser des mécanismes différents pour les utilisateurs normaux et les administrateurs.

Services et API tiers

Presque toutes les applications web incluent des ressources tierces qui sont chargées ou avec lesquelles le client interagit. Ceux-ci peuvent inclure :

  • Contenu actif (tel que des scripts, des feuilles de style, des polices et des iframes)
  • Contenu passif (tel que des images et des vidéos)
  • API externes
  • Boutons de médias sociaux
  • Réseaux publicitaires
  • Passerelles de paiement

Ces ressources sont demandées directement par le navigateur de l'utilisateur, ce qui les rend plus faciles à identifier à l'aide des outils de développement ou d'un proxy d'interception. Bien qu'il soit important de les identifier (car elles peuvent avoir un impact sur la sécurité de l'application), n'oubliez pas qu'elles sont généralement hors de portée pour les tests, car elles appartiennent à des tiers.

Composants réseau

Proxy inverse

Un proxy inverse se trouve devant un ou plusieurs serveurs backend et redirige les requêtes vers la destination appropriée. Ils peuvent être utilisés pour mettre en oeuvre diverses fonctionnalités, telles que :

  • Agir en tant qu'équilibreur de charge ou pare-feu d'application web
  • Permettre à plusieurs applications d'être hébergées sur une seule adresse IP ou un seul domaine (dans des sous-dossiers)
  • Mettre en oeuvre le filtrage IP ou d'autres restrictions
  • Mise en cache du contenu du backend pour améliorer les performances

Il n'est pas toujours possible de détecter un proxy inverse (surtout s'il n'y a qu'une seule application derrière lui), mais vous pouvez parfois l'identifier par :

  • Une incompatibilité entre le serveur frontal et l'application backend (comme un en-tête `Server: nginx` avec une application ASP.NET)
  • En-têtes en double (en particulier l'en-tête `Server`)
  • Plusieurs applications hébergées sur la même adresse IP ou le même domaine (surtout si elles utilisent des langages différents)

Equilibreur de charge

Un équilibreur de charge se trouve devant plusieurs serveurs backend et répartit les requêtes entre eux afin de fournir une plus grande redondance et une plus grande capacité de traitement pour l'application.

Les équilibreurs de charge peuvent être difficiles à détecter, mais peuvent parfois être identifiés en effectuant plusieurs requêtes et en examinant les réponses pour détecter les différences, telles que :

  • Temps système incohérents
  • Différentes adresses IP internes ou noms d'hôtes dans les messages d'erreur détaillés
  • Différentes adresses renvoyées par Server-Side Request Forgery (SSRF)

Ils peuvent également être indiqués par la présence de cookies spécifiques (par exemple, les équilibreurs de charge F5 BIG-IP créeront un cookie appelé `BIGipServer`.

Réseau de diffusion de contenu (CDN)

Un réseau de diffusion de contenu (CDN) est un ensemble géographiquement distribué de serveurs proxy de mise en cache conçus pour améliorer les performances du site.

Il est généralement configuré en pointant le domaine public vers les serveurs du CDN, puis en configurant le CDN pour qu'il se connecte aux serveurs backend corrects (parfois appelés "origine").

Le moyen le plus simple de détecter un CDN est d'effectuer une recherche WHOIS pour les adresses IP vers lesquelles le domaine est résolu. S'ils appartiennent à une société CDN (telle qu'Akamai, Cloudflare ou Fastly - voir Wikipedia pour une liste plus complète), il est alors probable qu'un CDN soit utilisé.

Lors du test d'un site derrière un CDN, vous devez garder à l'esprit les points suivants :

  • Les adresses IP et les serveurs appartiennent au fournisseur de CDN et sont susceptibles d'être hors de portée pour les tests d'infrastructure
  • De nombreux CDN incluent également des fonctionnalités telles que la détection de robots, la limitation de débit et les pare-feu d'application web
  • Les CDN mettent généralement le contenu en cache. Par conséquent, les modifications apportées dans le backend peuvent ne pas apparaître immédiatement sur le site.

Si le site est derrière un CDN, il pourrait être utile d'identifier les serveurs backend. Si un contrôle d'accès approprié n'est pas appliqué, le testeur peut être en mesure de contourner le CDN (et toutes les protections qu'il offre) en accédant directement aux serveurs backend. Il existe une variété de méthodes différentes qui peuvent permettre d'identifier le système backend :

  • Les e-mails envoyés par l'application peuvent provenir directement du serveur backend, ce qui pourrait révéler son adresse IP
  • Le grinding DNS, les transferts de zone ou les listes de transparence des certificats pour un domaine peuvent le révéler sur un sous-domaine
  • La numérisation des plages IP connues pour être utilisées par l'entreprise peut aider à identifier le serveur backend
  • L'exploitation de Server-Side Request Forgery (SSRF) peut révéler l'adresse IP
  • Les messages d'erreur détaillés de l'application peuvent exposer des adresses IP ou des noms d'hôtes

Composants de sécurité

Pare-feu réseau

La plupart des serveurs web seront protégés par un pare-feu de filtrage de paquets ou d'inspection dynamique, qui bloque tout trafic réseau qui n'est pas requis. Pour détecter cela, effectuez une analyse de port du serveur et examinez les résultats.

Si la majorité des ports sont affichés comme "fermés" (c'est-à-dire qu'ils renvoient un paquet `RST` en réponse au paquet `SYN` initial), cela suggère que le serveur peut ne pas être protégé par un pare-feu. Si les ports sont affichés comme "filtrés" (c'est-à-dire qu'aucune réponse n'est reçue lors de l'envoi d'un paquet `SYN` à un port inutilisé), alors un pare-feu est très probablement en place.

De plus, si des services inappropriés sont exposés au monde (tels que SMTP, IMAP, MySQL, etc.), cela suggère soit qu'il n'y a pas de pare-feu en place, soit que le pare-feu est mal configuré.

Système de détection et de prévention des intrusions réseau

Un système de détection d'intrusion (IDS) réseau est conçu pour détecter les activités suspectes ou malveillantes au niveau du réseau, telles que l'analyse des ports ou des vulnérabilités, et émettre des alertes. Un système de prévention des intrusions (IPS) fonctionne de la même manière, mais prend également des mesures pour prévenir l'activité, généralement en bloquant l'adresse IP source.

Un IPS peut généralement être détecté en exécutant des outils d'analyse automatisés (tels qu'un scanner de ports) contre la cible, et en voyant si l'IP source est bloquée. Cependant, de nombreux outils au niveau de l'application peuvent ne pas être détectés par un IPS (en particulier s'il ne déchiffre pas TLS).

Pare-feu d'application web (WAF)

Un pare-feu d'application web (WAF) inspecte le contenu des requêtes HTTP et bloque celles qui semblent suspectes ou malveillantes. Ils peuvent également être utilisés pour appliquer dynamiquement d'autres contrôles tels que CAPTCHA ou la limitation de débit. Ils utilisent généralement un ensemble de signatures et d'expressions régulières connues, telles que l'OWASP Core Rule Set, pour identifier le trafic malveillant. Les WAF peuvent être efficaces pour se protéger contre certains types d'attaques telles que l'injection SQL ou le cross-site scripting, mais sont moins efficaces contre d'autres types tels que le contrôle d'accès ou les problèmes liés à la logique métier.

Un WAF peut être déployé à plusieurs endroits, notamment :

  • Sur le serveur web lui-même
  • Sur une machine virtuelle ou un appareil matériel séparé
  • Dans le cloud, devant le serveur backend

Etant donné qu'un WAF bloque les requêtes malveillantes, il peut être détecté en ajoutant des chaînes d'attaque courantes aux paramètres et en observant si elles sont bloquées ou non. Par exemple, essayez d'ajouter un paramètre appelé `foo` avec une valeur telle que `' UNION SELECT 1` ou `><script>alert(1)</script>`. Si ces requêtes sont bloquées, il est probable qu'il y ait un WAF en place. De plus, le contenu des pages de blocage peut fournir des informations sur la technologie spécifique utilisée. Enfin, certains WAF peuvent ajouter des cookies ou des en-têtes HTTP aux réponses qui peuvent révéler leur présence.

Si un WAF basé sur le cloud est utilisé, il peut être possible de le contourner en accédant directement au serveur backend, en utilisant les mêmes méthodes que celles décrites dans la section Réseau de diffusion de contenu (CDN).