La sécurité des API (Application Programming Interface security) est le sous-domaine d'AppSec dédié à la protection des interfaces machine-à-machine (REST, GraphQL, gRPC, WebSocket) qui représentent en 2026 80%+ du trafic web et mobile. C'est l'angle d'attaque dominant des incidents AppSec depuis 2022, selon Salt Labs Q1 2024 et Akamai SOTI Report 2024, les attaques API ont augmenté de 400% entre 2023 et 2025, avec API1 BOLA (Broken Object Level Authorization) représentant 40%+ des incidents exploités. Le référentiel central est l'OWASP API Security Top 10 2023 (publié janvier 2023), distinct du Top 10 web 2021. Cet article documente les 7 priorités à comprendre : périmètre API security vs AppSec/web sec, top 5 risques 2024-2025 (BOLA, BFLA, BOPLA), authentification (OAuth 2.1, JWT, mTLS), spécificités GraphQL, stack outillage 2026, mapping compliance et anti-patterns d'architecture API.
Pour les fondamentaux : voir OWASP Top 10 c'est quoi priorités 2026. Pour le contexte AppSec : voir AppSec définition priorités 2026.
Le bon mental model : API security ≠ web security, c'est une discipline distincte
Beaucoup de candidats abordent la sécurité API comme une extension du Top 10 web 2021. C'est faux à 60%. Les APIs ont des surfaces d'attaque, des authentifications, des autorisations et des protocoles distincts des apps web monolithiques. Les vulnérabilités les plus exploitées sur APIs (BOLA, BFLA, BOPLA, unrestricted resource consumption) ne sont pas dans le Top 10 web 2021 sous ces noms.
Mythe API security vs Réalité API security 2026
───────────────────────────────────── ──────────────────────────────────
« WAF + Top 10 web suffit » → API Top 10 2023 + spécificités REST/GraphQL
Authentification = JWT seul → OAuth 2.1 + mTLS + JWT short-lived + Vault rotation
Validation côté API gateway suffit → Validation gateway + service-level + business logic
GraphQL est sécurisé par design → 30-40% contrôles spécifiques en plus vs REST
Rate limiting global suffit → Rate limiting per-tenant + per-endpoint + per-user
APIs internes = pas de risque → East-West attaques, mTLS obligatoire microservices
1 audit annuel = couverture → API discovery continu + DAST automatisé
Position 1 : auditer une stack microservices avec uniquement OWASP Top 10 web 2021 = manquer 60-70% des risques exploitables. Le Top 10 web ne couvre pas BOLA, BFLA, BOPLA, unrestricted resource consumption, improper inventory management, qui sont les 5 catégories les plus exploitées sur APIs en 2024-2025. Utiliser OWASP API Top 10 2023 comme référentiel principal pour toute architecture moderne.
Position 2 : les WAF L7 traditionnels (signature-based, Cloudflare, Imperva, F5) sont inefficaces sur 70%+ des attaques API modernes (BOLA, BFLA = logique métier, pas pattern d'injection). Stack 2026 = WAF L7 (couche signature) + API gateway (Kong, Tyk, AWS API Gateway) + API security platform (Salt, Noname, 42Crunch) ou solution OSS (Spectral + ZAP + Nuclei + custom logic).
Priorité 1, OWASP API Security Top 10 2023 décortiqué
| Code | Catégorie | Apparu en | Description courte | CWE clés |
|---|---|---|---|---|
| API1 | Broken Object Level Authorization (BOLA) | 2019 | Accès objet d'un autre user via ID prédictible | CWE-639, CWE-285 |
| API2 | Broken Authentication | 2019 | JWT mal validé, refresh token abusé, brute force login | CWE-287, CWE-798 |
| API3 | Broken Object Property Level Authorization (BOPLA) | 2023 (fusion v2019 API3+API6) | Mass assignment, exposition props non autorisées | CWE-915, CWE-213 |
| API4 | Unrestricted Resource Consumption | 2019 (renommé) | Pas de rate limit, DoS économique cloud | CWE-770, CWE-400 |
| API5 | Broken Function Level Authorization (BFLA) | 2019 | Endpoint admin accessible user normal | CWE-285, CWE-862 |
| API6 | Unrestricted Access to Sensitive Business Flows | 2023 (nouveau) | Automation abuse (scalping, fake accounts) | CWE-840, CWE-799 |
| API7 | Server-Side Request Forgery (SSRF) | 2023 (nouveau, ex-A10 web) | API qui fetch URL utilisateur, pivot interne | CWE-918 |
| API8 | Security Misconfiguration | 2019 | Default creds, CORS too permissive, debug endpoint | CWE-16, CWE-1004 |
| API9 | Improper Inventory Management | 2019 | Zombie/shadow APIs, versions deprecated en prod | CWE-1059 |
| API10 | Unsafe Consumption of APIs | 2023 (nouveau) | Trust aveugle réponses APIs tierces | CWE-20, CWE-829 |
Top 5 statistiquement les plus exploités 2024-2025
# Données empiriques API attaques 2024-2025 (Salt Labs Q1 2024 + Akamai SOTI 2024)
prevalence_api = {
"API1 BOLA": "40%+ des incidents, IDOR + privilege escalation",
"API2 Broken Auth": "20% des incidents, JWT/OAuth misconfigs",
"API3 BOPLA": "12%, mass assignment + property leakage",
"API4 Unrestricted Resources": "10%, DoS economic + scraping",
"API9 Improper Inventory": "8%, shadow APIs en prod",
}
# Total top 5 = ~90% des incidents documentés 2024-2025Priorité 2, BOLA (API1) et BFLA (API5) : les 50% du problème
# ANTI-PATTERN BOLA, endpoint sans authz objet-level
@app.route("/api/orders/<int:order_id>", methods=["GET"])
@require_auth # auth ✓
def get_order(order_id):
return Order.get(order_id) # PAS de check : Order.user_id == current_user.id
# User A peut accéder à /api/orders/42 même si order 42 appartient à user B
# PATTERN CORRECT BOLA, authz objet-level systématique
@app.route("/api/orders/<int:order_id>", methods=["GET"])
@require_auth
def get_order(order_id):
order = Order.get(order_id)
if not order:
abort(404)
# CRITIQUE : check ownership ou autorisation explicite
if order.user_id != g.current_user.id and not g.current_user.has_role("admin"):
# Retourner 404 plutôt que 403 pour ne pas fuir l'existence de l'objet
abort(404)
return order
# ANTI-PATTERN BFLA, endpoint admin sans check role
@app.route("/api/users/<int:user_id>", methods=["DELETE"])
@require_auth
def delete_user(user_id):
User.delete(user_id) # PAS de check role admin
# PATTERN CORRECT BFLA
@app.route("/api/users/<int:user_id>", methods=["DELETE"])
@require_role("admin", "superadmin") # Décorateur qui valide le role
def delete_user(user_id):
if user_id == g.current_user.id and g.current_user.role == "superadmin":
abort(403, "cannot self-delete superadmin")
User.delete(user_id)Position 3 : la solution structurelle aux BOLA/BFLA n'est pas d'écrire des if/else dans chaque endpoint. C'est d'utiliser un middleware authz centralisé (OPA/Gatekeeper, Open Policy Agent, Cerbos, ou framework intégré comme Casbin) avec règles policy-as-code mappées sur le modèle de données. Tester systématiquement en CI avec dredd ou Schemathesis + scénarios authz.
Priorité 3, BOPLA (API3) : mass assignment + property leakage
# ANTI-PATTERN BOPLA, mass assignment user input → DB
@app.route("/api/users/me", methods=["PATCH"])
@require_auth
def update_me():
data = request.json
User.update(g.current_user.id, **data)
# User envoie { "email": "x@y.com", "is_admin": true } → escalade !
# PATTERN CORRECT BOPLA, DTO whitelist + Pydantic validation
from pydantic import BaseModel
class UserUpdateInput(BaseModel):
# Schéma explicite : seuls ces champs sont acceptés
email: EmailStr
display_name: str = Field(..., max_length=64)
bio: str = Field(default="", max_length=500)
# is_admin volontairement ABSENT, pas modifiable via cette route
@app.route("/api/users/me", methods=["PATCH"])
@require_auth
def update_me():
payload = UserUpdateInput.model_validate(request.json)
User.update(g.current_user.id, payload.model_dump(exclude_unset=True))
# ANTI-PATTERN property leakage, sérialisation entière de l'objet User
@app.route("/api/users/<int:user_id>", methods=["GET"])
def get_user(user_id):
user = User.get(user_id)
return user.to_dict() # Inclut password_hash, mfa_secret, internal_notes !
# PATTERN CORRECT, DTO de réponse explicite
class UserPublicResponse(BaseModel):
id: int
display_name: str
bio: str
avatar_url: str | None
# NE PAS inclure : email, password_hash, mfa_secret, internal_notes
@app.route("/api/users/<int:user_id>", methods=["GET"])
def get_user(user_id):
user = User.get(user_id)
return UserPublicResponse.model_validate(user).model_dump()Référence : CWE-915 (Improperly Controlled Modification of Dynamically-Determined Object Attributes) = mass assignment classique.
Priorité 4, Authentification API : OAuth 2.1 + JWT + mTLS
| Mécanisme | Use case 2026 | Recommandation |
|---|---|---|
| API keys statiques | B2B simple low-trust uniquement | Rotation 90 jours + IP whitelist |
| Basic Auth | À éviter en 2026 | Migrer vers OAuth ou API key |
| JWT auto-signé | Short-lived access token | RS256/ES256, expire 5-15 min, refresh rotation |
| OAuth 2.1 (draft RFC) | API B2C/B2B sérieuse | PKCE obligatoire, response_type=code, refresh rotation |
| OpenID Connect 1.0 | Auth fédérée | Sur OAuth 2.1, ID token séparé access token |
| mTLS (Mutual TLS) | Service-to-service microservices | Service mesh (Istio, Linkerd, Consul Connect) |
| SPIFFE/SPIRE | Workload identity zero-trust | Standard CNCF, intégré service mesh |
# Exemple OAuth 2.1 + PKCE flow (ce que tu dois faire en 2026)
# 1. Client génère code_verifier (random 43-128 chars) + code_challenge = SHA256(verifier)
# 2. Authorization request avec :
# - response_type=code (PAS implicit, deprecated OAuth 2.1)
# - code_challenge_method=S256
# - code_challenge=<hash>
# - state=<random anti-CSRF>
# - PKCE obligatoire (même pour clients confidentiels en 2.1)
# 3. Token endpoint exchange :
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=<auth_code>
&code_verifier=<verifier>
&client_id=<client_id>
&redirect_uri=<exact_match>
# 4. Response :
{
"access_token": "<JWT short-lived>",
"expires_in": 900, # 15 min recommandé
"refresh_token": "<opaque rotated>", # rotation à chaque use
"token_type": "Bearer",
"id_token": "<si OIDC>"
}# Validation JWT correcte 2026 (avec PyJWT)
import jwt
from cryptography.hazmat.primitives.serialization import load_pem_public_key
with open("public_key.pem") as f:
public_key = load_pem_public_key(f.read().encode())
try:
payload = jwt.decode(
token,
public_key,
algorithms=["RS256", "ES256"], # JAMAIS d'option "none"
audience="api.example.com", # CRITIQUE : valider aud
issuer="https://auth.example.com", # CRITIQUE : valider iss
options={
"require": ["exp", "iat", "iss", "aud", "sub"],
"verify_exp": True,
"verify_iat": True,
"verify_aud": True,
"verify_iss": True,
}
)
except jwt.ExpiredSignatureError:
abort(401, "token expired")
except jwt.InvalidTokenError as e:
# Pas de log du token complet (secret), juste l'erreur
logger.warning("invalid_jwt", extra={"error_type": type(e).__name__})
abort(401, "invalid token")Position 4 : tout JWT validé sans aud, iss, exp, et avec algorithms=["HS256"] accepté par défaut est exploitable. CVE historique 2018 : alg=none accepté = bypass total. CVE-2022-23529 (jsonwebtoken Node) = key confusion attack. Toujours whitelist explicite des algos + validation tous les claims standards.
Priorité 5, GraphQL spécifique : introspection, batch, depth limiting
// Configuration GraphQL sécurisée 2026 (Apollo Server / GraphQL Yoga)
const { ApolloServer } = require('@apollo/server');
const depthLimit = require('graphql-depth-limit');
const costAnalysis = require('graphql-cost-analysis').default;
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== 'production', // OFF en prod
formatError: (err) => {
// Pas de stacktrace en prod
if (process.env.NODE_ENV === 'production') {
return { message: err.message }; // Pas de extensions, path détaillé
}
return err;
},
validationRules: [
depthLimit(8), // max 8 nested levels
costAnalysis({
maximumCost: 1000,
defaultCost: 1,
variables: {},
onComplete: (cost) => {
if (cost > 500) logger.warn('expensive_query', { cost });
},
}),
],
// Disable batched queries en prod si non nécessaires
allowBatchedHttpRequests: false,
});| Risque GraphQL | Détail | Mitigation |
|---|---|---|
| Introspection en prod | Schéma complet exposé via __schema | Disable introspection en prod (Apollo, Yoga) |
| Deeply nested queries | users { posts { comments { author { posts { ... } } } } } → exponentiel | depth limit (8 max), complexity analysis |
| Batch query DoS | Array de 1000 queries en 1 requête | Disable batched HTTP, ou limit batch size 5-10 |
| Field-level authz oublié | Authz sur Query.X mais pas sur User.email field | shield (graphql-shield), graphql-armor |
| Aliases multiplication | user1: user(id:1) user2: user(id:2) ... user1000: | rate limit aliases ou max query size |
| Error fuites | Stacktrace + paths internes | formatError custom, errors normalisées |
Position 5 : la grosse erreur 2026 est de laisser introspection ON en prod sur GraphQL. Outils Clairvoyance et graphql-cop reconstituent le schéma même sans introspection si les erreurs détaillent les noms de fields. Configuration mature : introspection OFF + custom formatError + depth limit + complexity analysis.
Priorité 6, Stack outillage API security 2026
# Stack OSS API security 2026 minimum (équipe < 50 dev, ~0 € budget)
# === SAST API spec ===
brew install spectral # Lint OpenAPI/Swagger
spectral lint openapi.yaml # Détecte problèmes spec
# === DAST + fuzzing ===
brew install zap # OWASP ZAP avec OpenAPI import
docker run --rm -v $(pwd):/zap/wrk owasp/zap2docker-stable \
zap-api-scan.py -t /zap/wrk/openapi.yaml -f openapi -r api-report.html
# === Fuzzing API spec-driven ===
pip install schemathesis # Property-based testing OpenAPI
schemathesis run openapi.yaml --base-url https://api.example.com --hypothesis-deadline=10000
# === Templates Nuclei API ===
brew install nuclei
nuclei -u https://api.example.com -t exposures/apis/ -t vulnerabilities/
# === Microsoft RESTler (Microsoft Research) ===
git clone https://github.com/microsoft/restler-fuzzer
# Fuzz stateful basé sur OpenAPI
# === API Gateway runtime ===
helm install kong kong/kong # Open source, plugins nombreux
# Alternatives : Tyk (OSS), AWS API Gateway, Kubernetes Gateway API
# === Service mesh mTLS ===
istioctl install --set profile=demo # Istio 2026
# Alternatives : Linkerd, Cilium Service Mesh
# === GraphQL specifics ===
# InQL (Burp Suite extension), GraphQL pentest
# Clairvoyance (introspection bypass)
git clone https://github.com/nikitastupin/clairvoyance
python3 -m clairvoyance -u https://api.example.com/graphql -o schema.json
# === API Discovery / Inventory ===
# Apicurio Registry (OSS), registry OpenAPI
# Salt Security, Noname Security, 42Crunch (commerciaux pour scale-ups+)| Catégorie | Outil OSS 2026 | Outil commercial alternative | Cible équipe |
|---|---|---|---|
| API spec linting | Spectral | 42Crunch API Audit | <50 dev OSS suffit |
| DAST API | OWASP ZAP + import OpenAPI | Burp Suite Enterprise, Salt | <50 dev OSS suffit |
| Fuzzing | RESTler + Schemathesis | API Fuzzer commercial | <50 dev OSS suffit |
| Discovery / Inventory | Apicurio + scrapers | Salt Security, Noname, 42Crunch | 50+ APIs commercial recommandé |
| Runtime gateway | Kong, Tyk, K8s Gateway API | AWS API Gateway, Apigee, Mulesoft | Selon cloud |
| Service mesh mTLS | Istio, Linkerd, Cilium | (commercial = managed K8s) | Microservices 10+ |
| Runtime protection | Falco + custom rules | Salt, Noname, Cequence | 50+ APIs commercial |
Priorité 7, Mapping API security ↔ frameworks compliance 2026
| Référentiel | Pertinence pour API security | Mapping clé |
|---|---|---|
| OWASP API Top 10 2023 | Core | API1-API10 |
| OWASP ASVS v4.0.3 chapitre V13 | Audit technique API | V13.1-V13.4 (REST, GraphQL, gRPC) |
| NIST SP 800-204 (Microservices security) | Architecture microservices | Service mesh + identity |
| NIST SP 800-204A/B/C (Service mesh, Microservices building blocks) | Architecture cloud-native | mTLS + zero-trust |
| PCI DSS 4.0 Req. 6.4 | Compliance paiement | Authz + audit trail APIs |
| DSP2 / Open Banking (PSD2 EBA RTS) | API bancaires UE | Strong Customer Authentication, certs eIDAS |
| NIS2 (transposée FR octobre 2024) | Compliance OIV/OSE FR | Article 21 mesures techniques |
| DORA (applicable 17 janvier 2025) | Compliance finance UE | RTS sur ICT third-party (APIs externes) |
| EU CRA (entrée vigueur 11 décembre 2024, applicable 2027) | Compliance produit | Annexe I.1 sur APIs intégrées |
| GDPR / RGPD Article 32 | Privacy by design | API exposing PII = controles renforcés |
Position 6 : les APIs B2B FinTech/Open Banking en 2026 doivent simultanément se conformer à : OWASP API Top 10 2023 + DSP2 + NIS2 + DORA. C'est le secteur où les contraintes API security sont les plus fortes, banques, néo-banques (Lydia, Spendesk), agrégateurs comptes (Bridge, Tink), payment providers (Stripe, Lemonway).
Erreurs fréquentes API security 2026
| Erreur | Symptôme / risque | Fix |
|---|---|---|
| Authz oubliée objet-level (BOLA) | API1, IDOR via ID prédictible | UUID v4 obligatoire + middleware authz centralisé OPA/Cerbos |
| JWT sans validation aud/iss | Token cross-API exploitable | Validation explicite tous claims standards + algos whitelist |
| Mass assignment user input → DB | API3 BOPLA, escalade privilèges | DTO whitelist Pydantic/Zod, jamais **data direct |
| Sérialisation entière de l'objet | API3 fuite props sensibles | DTO de réponse explicite |
| Pas de rate limiting per-user | API4, DoS + scraping + economic abuse | Rate limit per-user/per-tenant + global cap |
| Shadow APIs en prod | API9, vieilles versions vulnérables | API discovery continu, déprécation programmée |
| Introspection GraphQL en prod | Schéma exposé, recon facilité | introspection: false en prod |
| WAF L7 seul comme défense | BOLA/BFLA invisibles aux signatures | Stack WAF + API gateway + authz middleware |
| API keys statiques sans rotation | Leak = compromission permanente | OAuth 2.1 + Vault rotation 90 jours max |
| mTLS oublié microservices internes | East-West attaques après pivot | Service mesh Istio/Linkerd + SPIFFE workload identity |
| OAuth 2.0 sans PKCE | CSRF + interception code | OAuth 2.1 ou OAuth 2.0 + PKCE + state |
CORS too permissive (*) | Cross-origin abuse | Whitelist origines explicites, jamais Access-Control-Allow-Origin: * sur APIs avec auth |
Pour aller plus loin
- OWASP Top 10 c'est quoi priorités 2026, référentiel des 10 risques web 2021.
- AppSec définition priorités 2026, programme AppSec global.
- Secure coding définition priorités 2026, 7 principes secure coding.
- DevSecOps c'est quoi vraiment, concept englobant et anti-patterns.
- Pipeline CI/CD sécurisé exemple, pipeline complet annoté.
- Audit LLM security comment ça marche, méthodologie audit IA / LLM APIs.
- Salaire DevSecOps priorités 2026, tarification niches premium.
Points clés à retenir
- API security = sous-domaine d'AppSec dédié aux interfaces machine-à-machine (REST/GraphQL/gRPC). 80%+ du trafic web 2026 = APIs. +400% attaques API 2023-2025 (Salt Labs Q1 2024).
- Référentiel central : OWASP API Security Top 10 2023 (publié janvier 2023). Distinct du Top 10 web 2021. Auditer microservices avec Top 10 web seul = manquer 60-70% des risques.
- Top 5 risques exploités 2024-2025 : API1 BOLA (40%+ incidents), API2 Broken Authentication (20%), API3 BOPLA (12%), API4 Unrestricted Resource Consumption (10%), API9 Improper Inventory (8%). Représentent ~90% des incidents documentés.
- Solution structurelle BOLA/BFLA = middleware authz centralisé policy-as-code (OPA, Cerbos, Casbin), pas if/else dans chaque endpoint. UUID v4 obligatoire pour ressources sensibles.
- BOPLA solution = DTO whitelist Pydantic/Zod en input + DTO de réponse explicite en output. Jamais
**datadirect dans User.update(), jamaisuser.to_dict()complet. - Authentification 2026 : OAuth 2.1 (PKCE obligatoire) externe + mTLS interne (service mesh Istio/Linkerd) + JWT short-lived (5-15 min, RS256/ES256, jamais HS256 sans secret long ni alg=none) + Vault rotation refresh tokens.
- GraphQL spécifique : introspection OFF en prod, depth limit (8), complexity analysis, batch HTTP disabled. Outils pentest : InQL, Clairvoyance, graphql-cop, graphql-armor.
- Stack outillage 2026 OSS minimum équipe <50 dev : Spectral (lint OpenAPI) + ZAP (DAST) + Schemathesis (fuzzing) + Nuclei + Kong (gateway) + Istio (mTLS) + Falco (runtime). Coût 0 €.
- WAF L7 traditionnel ineffective sur 70%+ attaques API modernes (BOLA/BFLA = logique métier). Stack 2026 = WAF + API gateway + API security platform OU stack OSS.
- Mapping compliance API security FR 2026 : OWASP API Top 10 2023 + ASVS V13 + NIST SP 800-204 + PCI DSS 4.0 + DSP2 + NIS2 (octobre 2024 FR) + DORA (janvier 2025) + EU CRA (décembre 2024).
- Salaires API Security Engineer FR 2026 : confirmé 65-80 k€, senior 80-100 k€, specialist API + cloud (AWS API Gateway, Azure APIM, Apigee) 90-115 k€. ~150-300 postes ouverts FR fin 2025.
- Top employeurs API Security FR 2026 : scale-ups SaaS API-first (Stripe, Mirakl, Algolia, Doctolib), FinTech ouverte (Lydia, Spendesk, Bridge, Tink), GraphQL natifs (Back Market, Doctolib).




