Aikido

Sécurité CORS : Au-delà de la configuration de base

Écrit par
Rez Moss

Nous avons tous connu ça : vous envoyez une requête API, attendez la réponse, et là, paf, l'erreur CORS apparaît dans la console de votre navigateur.

Pour de nombreux développeurs, le premier réflexe est de trouver une solution rapide : ajouter Access-Control-Allow-Origin: * et passer à autre chose. Cependant, cette approche passe complètement à côté de l'essentiel. CORS n'est pas qu'un simple obstacle de configuration, mais l'un des mécanismes de sécurité de navigateur les plus importants jamais conçus.

CORS, ou Cross-Origin Resource Sharing, existe pour protéger les utilisateurs tout en permettant une communication légitime entre applications web de différents domaines. Pourtant, il est souvent mal compris, mal configuré ou traité comme un bug à « contourner ».

Mais plus maintenant.

Dans ce guide, nous irons au-delà des bases. Vous apprendrez :

  • Pourquoi CORS existe et comment il a évolué à partir de la Same-Origin Policy (SOP)
  • Comment les navigateurs et les serveurs négocient réellement l'accès cross-origin
  • Ce qui fait échouer certaines configurations CORS, même lorsqu'elles semblent « correctes »
  • Comment gérer les requêtes preflight, les identifiants et les particularités des navigateurs de manière sécurisée

Au terme de ce guide, vous ne saurez pas seulement comment configurer CORS, mais vous comprendrez également pourquoi il se comporte de cette manière et comment concevoir vos API en toute sécurité en tenant compte de cela.

Qu'est-ce que CORS (et pourquoi il existe) 

CORS est une norme de sécurité des navigateurs qui définit comment les applications web d'une origine peuvent accéder en toute sécurité aux ressources d'une autre.

Pour comprendre la sécurité de CORS, vous devez d'abord savoir pourquoi il a été créé.

Bien avant que les API et les microservices ne dominent le web, les navigateurs suivaient une règle simple appelée la Same-Origin Policy (SOP).

Cette politique stipulait qu'une page web ne pouvait envoyer et recevoir des données que de la même origine, c'est-à-dire le même protocole, le même domaine et le même port.

Par exemple :

Tableau de comparaison des origines

URL A URL B Même origine ?
https://example.com/api https://example.com/users ✅ Oui
https://example.com http://example.com ❌ Non (protocole différent)
https://example.com https://api.example.com ❌ Non (hôte différent)
https://example.com https://example.com:8080 ❌ Non (port différent)

Cette restriction avait parfaitement du sens aux débuts du web, lorsque la plupart des sites web étaient monolithiques. Un seul site hébergeait son front-end, son back-end et ses ressources sous un seul domaine.

Mais à mesure que le web évoluait avec les API, les microservices et les intégrations tierces, cette même règle est devenue un obstacle. Les développeurs avaient besoin que les applications front-end communiquent avec d'autres domaines, tels que :

  • www.example.com communiquant avec api.example.com
  • Votre application se connectant à un CDN ou à un point de terminaison d'analyse
  • Des clients web appelant des API tierces (comme Stripe ou Google Maps)

La politique de même origine est devenue un mur qui bloquait les architectures modernes et distribuées.

C'est là qu'Cross-Origin Resource Sharing (CORS) est entré en jeu.

Plutôt que de supprimer complètement les restrictions des navigateurs, CORS a introduit une relaxation contrôlée de la SOP. Il a créé un moyen sécurisé pour les navigateurs et les serveurs de communiquer entre domaines, en toute sécurité, et uniquement lorsque les deux parties sont d'accord.

Imaginez la situation ainsi : la SOP est une porte verrouillée qui ne laisse personne entrer, et CORS est la même porte, mais avec une liste d'invités et un videur vérifiant les identités.

Cet équilibre entre flexibilité et protection est ce qui rend la configuration CORS critique pour chaque application web moderne.

Comprendre la politique de même origine (SOP)

Avant d'aller plus loin dans la configuration CORS, il est essentiel de comprendre son fondement : la politique de même origine (SOP).

Comme indiqué précédemment, la SOP est la première ligne de défense du navigateur contre les comportements malveillants sur le web. Elle empêche un site web d'accéder librement aux données d'un autre, ce qui pourrait exposer des informations sensibles comme les cookies, les jetons d'authentification ou les données personnelles.

Voici comment cela fonctionne en pratique : lorsqu'une page web se charge dans votre navigateur, elle se voit attribuer une origine basée sur trois éléments : le protocole, l'hôte et le port :

https://   api.example.com   :443
^          ^                 ^
protocole   hôte              port

Deux URL sont considérées comme de même origine uniquement si ces trois parties correspondent. Sinon, le navigateur les traite comme étant d'origine différente.

Cette règle simple empêche les actions intersites malveillantes. Sans elle, un site aléatoire pourrait charger le tableau de bord de votre banque en ligne dans un cadre invisible, lire votre solde et l'envoyer à un attaquant, le tout sans votre consentement.

En bref, la SOP existe pour isoler le contenu entre différents sites, garantissant que chaque origine est une zone de sécurité autonome.

Pourquoi la SOP seule n'était pas suffisante

La politique de même origine fonctionnait parfaitement lorsque les sites web étaient autonomes. Mais à mesure que le web évoluait vers un écosystème d'API, de microservices et d'architectures distribuées, cette règle stricte est devenue une limitation majeure.

Les applications modernes devaient :

  • Appeler leurs propres API hébergées sur différents sous-domaines (app.example.com → api.example.com)
  • Récupérer des ressources depuis des CDN ou des services tiers
  • S'intégrer avec des API externes comme Stripe, Firebase ou Google Maps

Sous la SOP, ces requêtes légitimes d'origine différente étaient bloquées. Les développeurs ont essayé toutes les solutions de contournement possibles, y compris JSONP, les proxys inverses ou les domaines dupliqués, mais ces correctifs étaient soit non sécurisés, soit extrêmement complexes.

C'est là que CORS (Cross-Origin Resource Sharing) a changé la donne.

CORS a introduit un système d'établissement de liaison qui a permis aux navigateurs et aux serveurs de négocier la confiance. Au lieu de rompre la SOP, il l'a étendue, offrant un moyen de mettre en liste blanche de manière sécurisée des origines spécifiques pour la communication inter-domaines.

Comment fonctionne CORS : Le flux au niveau du protocole

Comme indiqué précédemment, lorsque votre navigateur effectue une requête vers une origine différente, il ne l'envoie pas aveuglément. Au lieu de cela, il suit un protocole CORS bien défini : un échange bidirectionnel entre le navigateur et le serveur pour déterminer si la requête doit être autorisée.

Essentiellement, CORS fonctionne via les en-têtes HTTP. Le navigateur joint un en-tête Origin à chaque requête cross-origin, indiquant au serveur l'origine de la requête. Le serveur répond ensuite avec un ou plusieurs en-têtes Access-Control-* qui définissent ce qui est autorisé.

Voici un exemple simplifié de cette conversation :

# Request
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com

# Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/json

{"message": "Success"}
Flux Requête-Réponse CORS
Flux Requête-Réponse CORS

Dans ce cas, le serveur autorise explicitement l'origine https://app.example.com à accéder à sa ressource. Le navigateur vérifie cette réponse, confirme la correspondance et transmet les données à votre JavaScript.

Mais si les origines ne correspondent pas ou si les en-têtes de réponse sont manquants ou incorrects, le navigateur bloque silencieusement la réponse. Vous ne verrez pas les données, seulement ce message frustrant d'« erreur CORS » dans votre console.

Il est important de noter que CORS ne rend pas un serveur plus sécurisé en soi. Au lieu de cela, il applique des règles d'engagement entre les navigateurs et les serveurs, une couche de sécurité qui garantit que seules les origines fiables peuvent accéder aux ressources protégées.

Types de requêtes CORS

CORS définit deux types principaux de requêtes : simples et pré-vérifiées. La différence réside dans le niveau de vérification effectué par le navigateur avant d'envoyer les données.

1. Requêtes simples

Une requête simple est le type le plus direct. Elle est automatiquement autorisée par les navigateurs tant qu'elle respecte des règles spécifiques :

  • Utilise l'une de ces méthodes : GET, HEAD ou POST

  • N'inclut que certains en-têtes :

    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (mais uniquement application/x-www-form-urlencoded, multipart/form-data ou text/plain)
  • N'utilise pas d'en-têtes personnalisés ou de flux

Voici à quoi cela ressemble :

# Request
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com

# Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Content-Type: application/json

{"message": "This is the response data"}

Dans ce cas :

  • Le navigateur ajoute automatiquement l'en-tête Origin.
  • Le serveur doit renvoyer Access-Control-Allow-Origin avec une origine correspondante.
  • Si l'origine ne correspond pas ou est manquante, le navigateur bloque la réponse.

2. Requêtes Preflight

Les choses deviennent plus intéressantes avec les requêtes non simples. Par exemple, lorsque vous utilisez des méthodes comme PUT, DELETE, ou des en-têtes personnalisés tels que Authorization.

Avant d'envoyer la requête réelle, le navigateur effectue une vérification preflight à l'aide d'une requête OPTIONS. Cette étape garantit que le serveur autorise explicitement l'opération prévue.

Voici un exemple :

# Preflight Request
OPTIONS /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type, authorization

# Preflight Response
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: PUT, POST, GET, DELETE
Access-Control-Allow-Headers: content-type, authorization
Access-Control-Max-Age: 3600

# Actual Request (only sent if preflight succeeds)
PUT /api/data HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Content-Type: application/json
Authorization: Bearer token123

{"data": "update this resource"}

Dans cette séquence :

  1. Le navigateur détecte une requête non simple.
  2. Il envoie une requête OPTIONS preflight, demandant la permission pour la méthode et les en-têtes réels.
  3. Le serveur répond avec les méthodes, les en-têtes et les origines qu'il autorise.
  4. Si la vérification preflight réussit, le navigateur envoie la requête réelle. Sinon, il la bloque.

Gestion des identifiants dans CORS

Lorsque vous traitez avec des API qui nécessitent une authentification comme les cookies, les jetons ou les connexions basées sur des sessions, CORS se comporte différemment.

Par défaut, les navigateurs traitent les requêtes cross-origin comme non authentifiées pour des raisons de sécurité. Cela signifie que les cookies ou les en-têtes d'authentification HTTP ne sont pas inclus automatiquement.

Pour activer les requêtes authentifiées en toute sécurité, deux étapes clés doivent être respectées :

1. Le client doit explicitement autoriser les credentials :

fetch('https://api.example.com/data', {
  credentials: 'include'
})

2. Le serveur doit explicitement les autoriser :

Access-Control-Allow-Credentials: true

Mais il y a un piège, et il est de taille.

Lorsque Access-Control-Allow-Credentials est défini sur true, vous ne pouvez pas utiliser de wildcard (*) dans Access-Control-Allow-Origin. Les navigateurs rejetteront la réponse si vous essayez.

C'est parce que permettre à toutes les origines d'envoyer des requêtes authentifiées annulerait tout l'objectif de la sécurité CORS ; cela permettrait à n'importe quel site sur internet d'accéder aux données privées liées à la session d'un utilisateur.

Donc, au lieu de ceci :

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

Vous devriez toujours utiliser une origine spécifique :

Access-Control-Allow-Origin: https://yourapp.com
Access-Control-Allow-Credentials: true

Si votre API dessert plusieurs domaines de confiance, vous pouvez retourner dynamiquement l'en-tête d'origine correct côté serveur :

const allowedOrigins = ['https://app1.com', 'https://app2.com'];
const origin = req.headers.origin;

if (allowedOrigins.includes(origin)) {
  res.setHeader('Access-Control-Allow-Origin', origin);
  res.setHeader('Access-Control-Allow-Credentials', 'true');
}

Cette approche garantit que vos requêtes authentifiées restent sécurisées et intentionnelles, et non ouvertes à quiconque tente d'y accéder.

Comment les navigateurs déterminent quelles requêtes sont éligibles au CORS

Avant même qu'une requête n'atteigne votre serveur, le navigateur décide si elle est soumise aux règles CORS.

Cette décision dépend de l'origine de la requête et si elle cible un autre domaine, port ou protocole.

Par exemple :

  • Requête vers https://api.example.com depuis une page servie à https://example.com : ✅ CORS s'applique (sous-domaine différent).
  • Requête vers https://example.com:3000 depuis https://example.com : ✅ CORS s'applique (port différent).
  • Requête vers https://example.com depuis le même domaine et port : ❌ CORS ne s'applique pas.

Si le navigateur détecte qu'une requête traverse les origines, il inclut automatiquement l'en-tête Origin dans la requête :

Origin: https://example.com

Cet en-tête indique au serveur l'origine de la requête et c'est ce que le serveur utilise pour décider d'autoriser ou de bloquer l'accès.

Si la réponse ne contient pas les bons en-têtes (comme Access-Control-Allow-Origin), le navigateur bloque simplement l'accès à la réponse, même si le serveur en a techniquement envoyé une.

C'est une distinction importante : le navigateur applique le CORS, pas le serveur.

Vérifications de sécurité internes, XMLHttpRequest vs Fetch, et différences entre navigateurs

Tous les navigateurs ne gèrent pas le CORS de la même manière, mais ils suivent tous le même modèle de sécurité : ne jamais faire confiance aux données cross-origin à moins d'une autorisation explicite.

Ce qui diffère, c'est la rigueur avec laquelle ils appliquent les règles et auxquelles API ils les appliquent.

1. La vérification de sécurité CORS interne

Lorsqu'un navigateur reçoit une réponse à une requête cross-origin, il effectue une étape de validation interne avant d'exposer la réponse à votre code JavaScript.

Il vérifie les en-têtes tels que :

  • Access-Control-Allow-Origin : doit correspondre à l'origine de la requête (ou être * dans certains cas).
  • Access-Control-Allow-Credentials : doit être true si des cookies ou des jetons d'authentification sont impliqués.
  • Access-Control-Allow-Methods et Access-Control-Allow-Headers : doivent correspondre à la requête preflight originale si une a été envoyée.

Si l'une de ces vérifications échoue, le navigateur ne génère pas d'erreur HTTP, il bloque simplement l'accès à la réponse et enregistre une erreur CORS dans la console.

Cela rend le débogage délicat, car la requête réseau réelle a tout de même réussi, mais le navigateur masque le résultat par sécurité.

2. XMLHttpRequest vs Fetch

Les deux, XMLHttpRequest et l'API moderne fetch(), supportent le CORS, mais ils se comportent légèrement différemment en ce qui concerne les identifiants et les valeurs par défaut.

Avec XMLHttpRequest :

  • Les cookies et l'authentification HTTP sont envoyés automatiquement si withCredentials est défini sur true.
  • Le comportement du preflight dépend de l'ajout d'en-têtes personnalisés.

Avec Fetch :

  • Les identifiants (cookies, authentification HTTP) ne sont pas inclus par défaut.
  • Vous devez les activer explicitement en utilisant :
fetch("https://api.example.com/data", {
	credentials: "include"
});
  • Fetch traite également les redirections de manière plus stricte sous CORS, car il ne suivra pas les redirections cross-origin sauf si elles sont autorisées.

Ainsi, bien que Fetch soit plus propre et plus moderne, il est également moins indulgent si vous oubliez un en-tête ou manquez une règle de credential.

3. Différences et particularités des navigateurs

Même si la spécification CORS est standard, les navigateurs l'implémentent avec de subtiles différences :

  • Safari peut être excessivement strict avec les cookies et les requêtes authentifiées, surtout lorsque les cookies tiers sont bloqués.
  • Firefox met parfois en cache les réponses preflight échouées plus longtemps que prévu, ce qui entraîne des résultats incohérents lors des tests.
  • Chrome applique CORS sur certaines chaînes de redirection de manière plus agressive que d'autres.

En raison de ces différences, une configuration qui fonctionne parfaitement sur un navigateur peut échouer silencieusement sur un autre.

C'est pourquoi il est essentiel de tester les configurations CORS sur différents navigateurs, surtout lorsque des identifiants ou des redirections sont impliqués.

Gestion côté serveur de l'en-tête Origin

Alors que le navigateur applique CORS, la prise de décision réelle se fait côté serveur.

Lorsque le navigateur envoie une requête cross-origin, il inclut toujours l'en-tête Origin. Le rôle du serveur est d'inspecter cet en-tête, de décider s'il doit l'autoriser et de renvoyer les en-têtes CORS corrects en réponse.

1. Validation de l'Origin

Une requête typique pourrait se présenter ainsi : Origin: https://frontend.example.com

Côté serveur, votre code doit vérifier si cet origin est autorisé. L'approche la plus simple (et la plus sûre) consiste à maintenir une liste blanche (allowlist) de domaines de confiance :

const allowedOrigins = ["https://frontend.example.com", "https://admin.example.com"];
if (allowedOrigins.includes(req.headers.origin)) {
  res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
}

Cela garantit que seuls les clients connus peuvent accéder à votre API, tandis que les autres ne reçoivent aucune permission CORS.

Évitez de renvoyer Access-Control-Allow-Origin: * si votre API gère des cookies, des jetons ou d'autres identifiants.

2. Gestion des requêtes Preflight

Pour les requêtes preflight OPTIONS, le serveur doit répondre avec la même attention que pour les requêtes principales.
Une réponse preflight complète inclut :

Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

Ces en-têtes indiquent au navigateur ce qui est autorisé et la durée pendant laquelle il peut mettre cette décision en cache. Si l'un d'entre eux est manquant ou incorrect, le navigateur bloquera la requête suivante, même si votre point de terminaison fonctionne correctement.

3. Configuration dynamique des en-têtes CORS

Dans les systèmes complexes (tels que les plateformes multi-locataires ou les API avec plusieurs clients), les origines autorisées peuvent nécessiter d'être dynamiques.

Par exemple :

const origin = req.headers.origin;

if (origin && origin.endsWith(".trustedclient.com")) {
  res.setHeader("Access-Control-Allow-Origin", origin);
}

Ce modèle permet d'autoriser tous les sous-domaines d'un domaine de confiance tout en filtrant les sources inconnues.

Assurez-vous simplement de valider les origines avec soin et ne faites pas de correspondance de chaînes sur les entrées utilisateur sans contraintes, sinon des attaquants pourraient forger des en-têtes qui semblent valides.

4. Pourquoi « Ça fonctionne dans Postman » ne signifie pas que c'est correctement configuré

L'une des plus grandes idées fausses concernant CORS est la suivante : « Ça fonctionne dans Postman, donc ça doit être un problème de navigateur. »

Postman n'applique pas du tout CORS, car ce n'est pas un navigateur.

Cela signifie que même une API complètement ouverte sans en-têtes Access-Control-* répondra correctement dans Postman, mais échouera immédiatement dans Chrome ou Firefox.

Donc, si votre API fonctionne dans Postman mais pas dans votre application web, vos en-têtes CORS sont probablement incomplets ou mal configurés.

Erreurs de configuration CORS courantes (et comment les éviter)

1. Utilisation de Access-Control-Allow-Origin: * avec des identifiants

C'est l'erreur la plus fréquente et la plus dangereuse.
Si votre réponse inclut les deux :

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

…le navigateur bloquera automatiquement la requête.

La spécification CORS interdit l'utilisation de jokers (wildcards) lorsque des identifiants sont inclus, car cela permettrait à n'importe quel site d'accéder aux données utilisateur liées aux cookies ou aux jetons d'authentification.

Correction : Retournez toujours une origine spécifique lorsque des identifiants sont utilisés :

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

2. Oubli de la gestion des requêtes de pré-vérification

De nombreuses API répondent correctement aux requêtes GET et POST mais oublient la requête de pré-vérification OPTIONS.

Lorsque cela se produit, le navigateur n'atteint jamais votre point de terminaison réel, et il bloque la requête principale après l'échec de la pré-vérification.

Correction : Gérez explicitement les requêtes OPTIONS et répondez avec les en-têtes appropriés :

if (req.method === "OPTIONS") {
  res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
  res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
  res.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
  return res.sendStatus(204);
}

3. Désalignement des en-têtes de requête et de réponse

Un autre problème subtil : votre requête de pré-vérification peut demander certains en-têtes, mais le serveur ne les autorise pas explicitement.

Par exemple, si votre requête inclut :

Access-Control-Request-Headers: Authorization, Content-Type

...mais le serveur ne répond qu'avec :

Access-Control-Allow-Headers: Content-Type

...le navigateur le bloque. Les deux listes doivent correspondre exactement.

Solution : Assurez-vous que votre en-tête Access-Control-Allow-Headers inclut tous les en-têtes que le client pourrait envoyer, en particulier Authorization, Accept et les en-têtes personnalisés.

4. Retour de plusieurs en-têtes Access-Control-Allow-Origin

Certains proxies ou frameworks mal configurés envoient plusieurs en-têtes Access-Control-Allow-Origin (par exemple, un * statique et une origine dynamique).

Les navigateurs considèrent cela comme invalide et bloquent entièrement la requête.

Solution : Retournez toujours un seul en-tête Access-Control-Allow-Origin valide.

5. Oubli des restrictions de méthode

Si vous n'incluez pas toutes les méthodes autorisées dans Access-Control-Allow-Methods, les navigateurs rejetteront les requêtes légitimes.

Par exemple, une API pourrait prendre en charge PUT, mais votre réponse de pré-vérification n'autorise que GET et POST.

Solution : Listez chaque méthode prise en charge ou faites correspondre dynamiquement vos routes d'API pour assurer la cohérence.

6. Ignorer les réponses de pré-vérification mises en cache

Les navigateurs modernes mettent en cache les résultats des pré-vérifications pour des raisons de performance.
Mais si votre serveur ou CDN met en cache les réponses sans varier par Origin, vous pourriez accidentellement envoyer les mauvais en-têtes CORS à un autre client.

Solution : Utilisez l'en-tête Vary: Origin pour vous assurer que les réponses sont mises en cache séparément par origine.

Les problèmes CORS proviennent rarement d'une seule grosse erreur. Ils sont généralement le résultat de plusieurs petites incohérences entre les attentes du navigateur et la configuration du serveur. Comprendre ces schémas vous aide à éviter les cycles de débogage interminables d'« erreurs CORS ».

CORS n'est pas l'ennemi, c'est l'incompréhension qui l'est

À première vue, CORS semble être une barrière inutile, ou plutôt un gardien qui interrompt vos requêtes et ralentit le développement.

Mais en réalité, c'est l'une des fonctionnalités de sécurité de navigateur les plus importantes jamais conçues.

Une fois que vous comprenez son fonctionnement, vous cessez de voir les « erreurs CORS » comme des échecs aléatoires, mais elles deviennent plutôt des signaux indiquant que votre client et votre serveur doivent mieux s'aligner sur la confiance, les en-têtes ou les identifiants.

Que vous construisiez une application monopage ou un écosystème d'API distribuées, CORS est votre allié pour assurer la sécurité des utilisateurs tout en permettant une communication inter-domaines sécurisée.

Ainsi, la prochaine fois que vous rencontrerez ce message familier dans la console, ne vous tournez pas vers le caractère générique (wildcard). Lisez les en-têtes, suivez la logique, et laissez votre compréhension, et non une solution de fortune aléatoire, guider la correction !

Partager :

https://www.aikido.dev/blog/cors-security-beyond-basic-configuration

Abonnez-vous pour les actualités sur les menaces.

Commencez dès aujourd'hui, gratuitement.

Commencer gratuitement
Sans carte bancaire

Sécurisez votre environnement dès maintenant.

Sécurisez votre code, votre cloud et votre environnement d’exécution dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Aucune carte de crédit requise | Résultats en 32 secondes.