80 % du trafic web est aujourd’hui de l’API. Les applications mobiles, les SPAs, les intégrations B2B, les microservices — tout passe par des API. Et les attaquants l’ont compris : selon Salt Security, les attaques sur les API ont augmenté de 681 % en 12 mois. Les DSI qui sécurisent leurs sites web mais pas leurs API protègent la porte d’entrée en laissant les fenêtres grandes ouvertes.
L’OWASP API Security Top 10 est la référence mondiale pour comprendre et contrer les menaces spécifiques aux API. Ce guide vous montre comment sécuriser vos APIs cloud contre chacune des 10 menaces, avec une architecture conforme NIS2 et DORA.
Pourquoi les API sont le maillon faible
Les chiffres qui comptent
| Statistique | Source |
|---|---|
| 80 % du trafic web = API | Akamai |
| 681 % d’augmentation des attaques API en 12 mois | Salt Security |
| 62 % des breaches impliquent une API | Noname Security |
| Temps moyen de détection d’une breach API : 277 jours | IBM |
| 40 % des entreprises n’ont aucune visibilité sur leurs API | Salt Security |
Le problème n°1 n’est pas le manque de solutions de sécurité — c’est le manque de visibilité. La plupart des DSI ne connaissent pas l’inventaire complet de leurs API. Les API shadow (non documentées, non monitorées) représentent en moyenne 30 % du parc API d’une entreprise.
Les 5 différences entre sécurité web et sécurité API
| Aspect | Site Web | API |
|---|---|---|
| Surface d’attaque | Pages, formulaires | Endpoints, paramètres, payloads JSON |
| Authentification | Session, cookie | Token JWT, OAuth2, clé API |
| Visibilité | Navigateur (visible) | Programmatique (invisible) |
| Documentation | Interface utilisateur | Swagger/OpenAPI (souvent absent) |
| Rate limiting | Facile (1 utilisateur = 1 navigateur) | Complexe (1 bot = 10 000 req/s) |
Un WAF protège les pages web. Pour les API, il faut une stratégie spécifique.
OWASP API Security Top 10 : les menaces et les parades
API1 — Broken Object Level Authorization (BOLA)
Le risque : un utilisateur accède aux données d’un autre utilisateur en modifiant l’ID dans la requête.
GET /api/v1/users/1234/orders
→ L'utilisateur 5678 remplace 1234 par 5678
GET /api/v1/users/5678/orders
→ Il voit les commandes de quelqu'un d'autre
Impact : fuite de données personnelles (RGPD), accès non autorisé aux données métier.
Parade :
# Middleware d'autorisation par objet
@app.middleware("http")
async def verify_object_access(request, user):
resource_owner_id = extract_owner_id(request)
if user.id != resource_owner_id and not user.is_admin:
raise HTTPException(403, "Accès refusé")
Conformité : BOLA = violation de l’article 32 RGPD (mesures techniques inappropriées). NIS2 exige le contrôle d’accès par nécessité (least privilege).
API2 — Broken Authentication
Le risque : authentification faible, tokens JWT non validés, credentials hardcoded.
| Faille courante | Exemple | Parade |
|---|---|---|
| Mot de passe dans le code | api_key: "sk-abc123" | Vault pour les secrets |
| JWT sans vérification | Accepter n’importe quel JWT | Vérifier la signature + expiration + issuer |
| Pas de rotation de tokens | Token valide indéfiniment | Refresh token + rotation tous les 15 min |
| Pas de MFA | Login par mot de passe seul | Keycloak MFA + OAuth2 |
Architecture d’authentification Keycloak :
┌──────────────┐ ┌─────────────────────┐ ┌──────────────┐
│ Application │────→│ KEYCLOAK │────→│ API │
│ (Client) │ │ │ │ (Resource) │
│ │ │ • OAuth2 / OIDC │ │ │
│ Access Token │ │ • JWT 15 min │ │ Valide le JWT │
│ Refresh Token│ │ • Refresh 24h │ │ Check scopes │
│ │ │ • MFA (TOTP/WebAuthn)│ │ Check roles │
└──────────────┘ └─────────────────────┘ └──────────────┘
Conformité : DORA exige une authentification forte pour les systèmes ICT financiers. NIS2 exige une politique de contrôle d’accès.
API3 — Broken Object Property Level Authorization (BOPLA)
Le risque : l’API expose trop de données. L’utilisateur demande un objet mais reçoit des champs qu’il ne devrait pas voir.
// Requête : GET /api/v1/users/me
// Réponse attendue : { "name": "Jean", "email": "jean@example.com" }
// Réponse réelle : {
// "name": "Jean",
// "email": "jean@example.com",
// "role": "admin", // ← ne devrait pas être exposé
// "salary": 85000, // ← données personnelles
// "password_hash": "$2b$..." // ← CRITIQUE
// }
Parade : séparer les DTO (Data Transfer Objects) des modèles de données :
# Modèle interne (jamais exposé)
class User(BaseModel):
id: int
name: str
email: str
role: str
salary: float
password_hash: str
# DTO public (seules les données autorisées)
class UserPublicDTO(BaseModel):
name: str
email: str
# DTO admin (plus de champs, mais jamais le hash)
class UserAdminDTO(BaseModel):
name: str
email: str
role: str
Conformité : minimisation des données = principe fondamental RGPD. Ne pas exposer plus de données que nécessaire.
API4 — Unrestricted Resource Consumption
Le risque : une API sans limites de ressources peut être exploité pour des attaques par déni de service, de l’extraction de données massives, ou des attaques par force brute.
| Type d’attaque | Impact | Parade |
|---|---|---|
| Rate limiting absent | 10 000 req/s épuisent le serveur | Rate limit par IP + par utilisateur |
| Pagination absente | GET /api/v1/users retourne 1 M d’enregistrements | Pagination obligatoire (max 100/page) |
| Payload géant | 500 MB JSON fait crasher le parser | Limitation de la taille du corps (1 MB max) |
| Requêtes coûteuses | ?expand=all fait 500 requêtes DB | Coût par requête + budget par utilisateur |
Architecture de rate limiting :
# Traefik middleware — Rate limiting par endpoint
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: api-rate-limit
spec:
rateLimit:
average: 100 # 100 req/s par utilisateur
burst: 200 # pic autorisé
period: 1s
# Différenciation par authentication
sourceCriterion:
requestHeaderName: "X-User-ID"
---
# Rate limiting spécifique pour les endpoints d'authentification
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-rate-limit
spec:
rateLimit:
average: 5 # 5 tentatives par minute
burst: 10
period: 1m
sourceCriterion:
ipStrategy:
depth: 1
Conformité : NIS2 exige la disponibilité des systèmes. DORA exige la résilience face aux surcharges.
API5 — Broken Function Level Authorization (BFLA)
Le risque : un utilisateur régulier accède aux endpoints administrateur.
# L'utilisateur régulier découvre l'endpoint admin :
POST /api/v1/admin/users
Authorization:Bearer <token_utilisateur_regulier>
# Si l'API ne vérifie que l'authentification (token valide)
# et pas l'autorisation (rôle admin), l'utilisateur peut créer des comptes
Parade : vérification systématique des rôles et permissions :
# Décorateur d'autorisation par rôle
def require_role(*roles):
def decorator(func):
@wraps(func)
async def wrapper(request, *args, **kwargs):
user = request.state.user
if user.role not in roles:
logger.warning(f"BFLA attempt: user {user.id} "
f"role={user.role} accessed {func.__name__}")
raise HTTPException(403, "Accès refusé")
return await func(request, *args, **kwargs)
return wrapper
return decorator
# Utilisation
@app.post("/api/v1/admin/users")
@require_role("admin", "superadmin")
async def create_user(request, user_data):
...
API6 — Unrestricted Access to Sensitive Business Flows
Le risque : automatisation de flux métier sensibles (réservation massives, création de comptes, scraping).
| Flux sensible | Attaque | Impact |
|---|---|---|
| Réservation | Bot qui réserve toutes les places | Rupture de stock artificielle |
| Création de comptes | 10 000 comptes en 5 minutes | Spam, fraude |
| Mot de passe oublié | 1 000 reset par minute | Déni de service par email |
| Checkout | Scraping des prix en temps réel | Avantage concurrentiel déloyal |
Parade : CAPTCHA, proof of work, et rate limiting contextuel :
# Proof of work pour les endpoints sensibles
@app.post("/api/v1/users/register")
async def register(request, registration):
# Vérifier le proof of work (hashcash)
if not verify_hashcash(registration.pow, difficulty=4):
raise HTTPException(400, "Proof of work invalide")
# Rate limiting strict : 3 comptes par heure par IP
if await redis.get(f"register:{request.client.host}"):
raise HTTPException(429, "Trop de tentatives")
# Créer le compte
user = await create_user(registration)
await redis.setex(f"register:{request.client.host}", 3600, "1")
return user
API7 — Server Side Request Forgery (SSRF)
Le risque : l’API permet de faire des requêtes vers des ressources internes.
# Endpoint vulnérable
@app.get("/api/v1/fetch-url")
async def fetch_url(url: str):
response = httpx.get(url) # ← SSRF ! L'URL peut pointer vers le réseau interne
return {"content": response.text}
# Attaque : GET /api/v1/fetch-url?url=http://169.254.169.254/latest/meta-data/
# → Récupère les metadata du cloud (IAM credentials, etc.)
Parade : liste blanche strict des domaines autorisés :
ALLOWED_DOMAINS = ["api.partner.com", "cdn.example.com"]
@app.get("/api/v1/fetch-url")
async def fetch_url(url: str):
parsed = urlparse(url)
if parsed.hostname not in ALLOWED_DOMAINS:
raise HTTPException(400, "Domaine non autorisé")
# Toujours interdire les IP internes
if is_private_ip(parsed.hostname):
raise HTTPException(400, "Adresse interne non autorisée")
...
API8 — Security Misconfiguration
Le risque : configuration par défaut, headers de sécurité absents, CORS permissif, verbosité excessive.
Checklist de configuration sécurisée :
# Headers de sécurité (Traefik middleware)
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: security-headers
spec:
headers:
# Anti-clickjacking
customFrameOptionsValue: "DENY"
# Force HTTPS
sslRedirect: true
stsSeconds: 31536000
stsIncludeSubdomains: true
# XSS protection
contentTypeNosniff: true
browserXssFilter: true
# CORS restrictif
accessControlAllowOrigin: "https://cloud-inspire.io"
accessControlAllowMethods: ["GET", "POST"]
accessControlMaxAge: 600
# Cache sensible
customResponseHeaders:
Cache-Control: "no-store"
Pragma: "no-cache"
X-Content-Type-Options: "nosniff"
Referrer-Policy: "strict-origin-when-cross-origin"
API9 — Improper Inventory Management
Le risque : des API obsolètes, non documentées, ou en version de test accessibles en production.
Réalité : la moyenne d’API shadow (non documentées) dans une entreprise est de 30 %. Chaque API non documentée est une surface d’attaque non monitorée.
Parade : registre centralisé des API :
#/api-registry.yml — Inventaire complet des API
api_gateway:
name: "Cloud Inspire API Gateway"
version: "2.1.0"
apis:
- name: "user-api"
version: "v2"
path: "/api/v2/users"
owner: "team-identity"
auth: "oauth2-keycloak"
rate_limit: "100/s"
status: "production"
- name: "order-api"
version: "v1"
path: "/api/v1/orders"
owner: "team-commerce"
auth: "oauth2-keycloak"
rate_limit: "50/s"
status: "production"
- name: "admin-api"
version: "v1"
path: "/api/v1/admin"
owner: "team-platform"
auth: "oauth2-keycloak+mfa"
rate_limit: "10/s"
status: "internal"
# Jamais exposé publiquement
API10 — Unsafe Consumption of APIs
Le risque : votre API est sécurisée, mais elle consomme des API tierces qui ne le sont pas. Le maillon faible n’est pas chez vous — il est chez votre partenaire.
Exemples :
- Votre API de paiement appelle un webhook tiers sans vérifier la signature
- Votre API d’intégration accepte les données d’un partenaire sans validation
- Votre API interne fait confiance aux données d’une API externe compromise
Parade : zéro confiance même envers les API partenaires :
# Validation de toutes les entrées, même des API partenaires
@app.post("/api/v1/webhooks/payment")
async def payment_webhook(request):
# 1. Vérifier la signature du webhook
if not verify_webhook_signature(request.body, request.headers["X-Signature"]):
raise HTTPException(401, "Signature invalide")
# 2. Valider le payload selon un schéma strict
try:
payment = PaymentWebhookSchema(**request.json())
except ValidationError as e:
raise HTTPException(400, f"Payload invalide: {e}")
# 3. Vérifier l'idempotence (pas de double traitement)
if await redis.get(f"webhook:{payment.id}"):
raise HTTPException(200, "Déjà traité")
# 4. Traiter
await process_payment(payment)
await redis.setex(f"webhook:{payment.id}", 86400, "1")
Architecture de sécurité API complète
Vue d’ensemble
┌───────────────────────────────────────────────────────────────┐
│ INTERNET │
└───────────────────────┬───────────────────────────────────────┘
│ HTTPS
┌───────────────────────▼───────────────────────────────────────┐
│ TRAEFIK (API Gateway) │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Rate Limit │ │ WAF Coraza │ │ Security Headers │ │
│ │ 100 req/s │ │ OWASP CRS │ │ CORS, CSP, HSTS │ │
│ └─────────────┘ └──────────────┘ └────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ TLS │ │ Routing │ │ Observabilité │ │
│ │ Auto (Let's)│ │ Path-based │ │ Logs → Loki │ │
│ └─────────────┘ └──────────────┘ └────────────────────────┘ │
└───────────────────────┬───────────────────────────────────────┘
│
┌───────────────────────▼───────────────────────────────────────┐
│ KEYCLOAK (Identity) │
│ OAuth2 / OIDC • JWT 15 min • Refresh 24h • MFA • SSO │
└───────────────────────┬───────────────────────────────────────┘
│ Token validé
┌───────────────────────▼───────────────────────────────────────┐
│ API SERVICES │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Users │ │ Orders │ │Payement│ │ Admin │ │
│ │ API │ │ API │ │ API │ │ API │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ │
│ │
│ Validation • Autorisation • Idempotence • Audit Log │
└───────────────────────────────────────────────────────────────┘
La stack de sécurité API Cloud Inspire
| Couche | Outil | Rôle | Protection OWASP |
|---|---|---|---|
| L4/L7 | Traefik | Rate limiting, TLS, routing | API4, API8 |
| L7 | Coraza WAF | OWASP CRS, virtual patching | API7, API8 |
| Identité | Keycloak | OAuth2/OIDC, JWT, MFA, SSO | API2, API5 |
| Autorisation | Middleware custom | BOLA, BFLA, BOPLA | API1, API3, API5 |
| Validation | JSON Schema | Entrées/sorties, schéma strict | API3, API10 |
| Observabilité | Grafana + Loki | Audit, monitoring, alertes | API6, API9 |
| Secrets | Vault | Rotation, jamais en clair | API2, API8 |
Conformité réglementaire
NIS2 : sécurité du réseau et des systèmes
| Mesure NIS2 | Réponse API |
|---|---|
| Sécurité du réseau (Art. 21.2.a) | WAF Coraza + rate limiting + TLS |
| Gestion des incidents | Audit logging de chaque appel API |
| Contrôle d’accès (Art. 21.2.d) | Keycloak RBAC + BOLA/BFLA checks |
| Gestion des vulnérabilités | API inventory + déploiement continu |
| Chiffrement (Art. 21.2.f) | TLS 1.3 partout + Vault pour les secrets |
DORA : résilience opérationnelle ICT
| Exigence DORA | Réponse API |
|---|---|
| Tests de résilience | Load testing des API (k6, Locust) |
| Gestion des tiers | Validation des webhooks tiers (API10) |
| Continuité d’activité | API versioning + rollback |
| Reporting d’incidents | Audit trail de chaque appel API |
RGPD : protection des données
| Principe | Mise en œuvre |
|---|---|
| Minimisation (Art. 5(1)(c)) | DTO séparés (API3/BOPLA) |
| Intégrité (Art. 5(1)(f)) | Validation JSON Schema + CORS restrictif |
| Confidentialité (Art. 32) | TLS 1.3 + authentification forte (Keycloak MFA) |
| Droit d’effacement (Art. 17) | API endpoint dédié DELETE /api/v1/users/me/data |
API Gateway : le point de contrôle central
Pourquoi un API Gateway
Dans une architecture microservices, chaque API a sa propre authentification, son propre rate limiting, ses propres headers de sécurité. C’est ingérable.
L’API Gateway centralise :
- Authentification : Keycloak vérifie le token une fois, l’API Gateway propage le contexte utilisateur
- Autorisation : vérification des rôles et scopes au gateway avant de router
- Rate limiting : 100 req/s par utilisateur, 5 req/min pour les endpoints d’auth
- Logging : chaque appel API est journalisé avec le contexte complet
- Transformation : versioning, header rewriting, payload filtering
Configuration Traefik API Gateway
# Traefik — Routage par path avec middlewares de sécurité
http:
routers:
user-api:
rule: "PathPrefix(`/api/v2/users`)"
service: "user-api"
middlewares:
- security-headers
- rate-limit-standard
- keycloak-auth
- waf-coraza
auth-api:
rule: "PathPrefix(`/api/v1/auth`)"
service: "auth-api"
middlewares:
- security-headers
- rate-limit-auth # Plus strict
- keycloak-auth
admin-api:
rule: "PathPrefix(`/api/v1/admin`)"
service: "admin-api"
middlewares:
- security-headers
- rate-limit-strict
- keycloak-auth-admin # MFA requis
- waf-coraza
Observabilité des API : dashboards et alertes
Métriques API essentielles
| Métrique | Seuil d’alerte | Action |
|---|---|---|
| Latence P95 | > 500 ms | Investigation performance |
| Taux d’erreur 4xx | > 5 % | Vérifier les paramètres clients |
| Taux d’erreur 5xx | > 1 % | Incident critique |
| Requêtes/s par endpoint | > 2x normal | Attaque probable |
| Token expiré | > 10 % | Problème d’authentification |
| BOLA attempts | > 0 | Alerte sécurité |
| Rate limit triggered | > 100/h | Attaque par force brute |
Dashboard Grafana
┌─────────────────────────────────────────────────────────────────┐
│ API SECURITY DASHBOARD │
├───────────────┬───────────────┬────────────────┬───────────────┤
│ Total req/s │ Error rate │ Avg latency │ Auth failures │
│ 1,247 │ 0.8% │ 142 ms │ 23 │
│ ↑ 12% │ ↓ 0.3% │ ↑ 8ms │ ↑ 5 │
├───────────────┴───────────────┴────────────────┴───────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Requêtes par endpoint (Top 10) │ │
│ │ /api/v2/users ███████████████████░ 340 req/s │ │
│ │ /api/v1/orders ██████████████░░░░░░ 230 req/s │ │
│ │ /api/v1/auth ██████████░░░░░░░░░░ 180 req/s │ │
│ │ /api/v1/admin ████░░░░░░░░░░░░░░░░ 70 req/s │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Attaques détectées (7 derniers jours) │ │
│ │ BOLA attempts ████████ 47 │ │
│ │ Rate limited █████████████████ 123 │ │
│ │ SSRF blocked ██ 3 │ │
│ │ SQL injection ████ 12 │ │
│ │ XSS blocked ██████ 31 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ OWASP API Top 10 Coverage │ │
│ │ API1 BOLA ████████████████████ 100% ✅ │ │
│ │ API2 Auth ████████████████████ 100% ✅ │ │
│ │ API3 BOPLA ███████████████░░░░ 85% ⚠️ │ │
│ │ API4 Rate Limit ██████████████████░ 95% ✅ │ │
│ │ API5 BFLA ████████████████████ 100% ✅ │ │
│ │ API6 Business ████████████████░░░ 90% ✅ │ │
│ │ API7 SSRF ████████████████████ 100% ✅ │ │
│ │ API8 Config ████████████████████ 100% ✅ │ │
│ │ API9 Inventory ████████████░░░░░░░ 65% ⚠️ │ │
│ │ API10 Consumer ██████████████████░ 92% ✅ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Audit API NIS2 : checklist en 10 points
| # | Contrôle | Statut |
|---|---|---|
| 1 | Inventaire complet des API (y compris shadow) | ☐ |
| 2 | Authentification forte (OAuth2 + MFA) | ☐ |
| 3 | Autorisation par objet (BOLA protection) | ☐ |
| 4 | Rate limiting par endpoint | ☐ |
| 5 | Validation des entrées (JSON Schema) | ☐ |
| 6 | Headers de sécurité (CORS, CSP, HSTS) | ☐ |
| 7 | TLS 1.3 sur tous les endpoints | ☐ |
| 8 | Audit logging de chaque appel | ☐ |
| 9 | Secrets dans Vault (jamais en clair) | ☐ |
| 10 | Tests de résilience (load testing) | ☐ |
Déploiement en 5 jours
| Jour | Action | Livrable |
|---|---|---|
| J1 | Inventaire API + Keycloak | Authentification OAuth2/OIDC opérationnelle |
| J2 | API Gateway Traefik + Sécurité | Rate limiting + headers + TLS + WAF |
| J3 | Autorisation BOLA/BFLA + Validation | Middleware d’autorisation par objet |
| J4 | Audit logging + Dashboards | Grafana API Security Dashboard |
| J5 | Tests de résilience + Documentation | Rapport de conformité NIS2/DORA |
Prérequis : Keycloak déployé, Traefik configuré, Coraza WAF installé.
Conclusion
Les API sont la porte d’entrée de votre infrastructure en 2026. Sécuriser le site web sans sécuriser les API, c’est verrouiller la porte d’entrée en laissant les fenêtres ouvertes. L’OWASP API Top 10 donne la carte des menaces — la stack Cloud Inspire (Keycloak + Traefik + Coraza + Grafana) donne la solution.
Pour le DSI en environnement réglementé, la sécurité des API n’est pas un bonus technique : c’est une obligation NIS2 (contrôle d’accès, gestion des incidents, traçabilité) et une exigence DORA (résilience opérationnelle, gestion des tiers). Chaque API non sécurisée est un risque réglementaire concret.
Cloud Inspire déploie la stack de sécurité API complète en 5 jours : inventaire, authentification, autorisation, rate limiting, WAF, et observabilité. Si votre entreprise a des API mais pas de stratégie de sécurité API, parlons-en.