Exploitation

Comportement en cas de panne, rotation des clés, exemples serveur, domaines et politique de sécurité du contenu.

Gestion des erreurs & fail-open

Si le service CaptchaCore est inaccessible, le comportement peut être configuré :

Fail-Open (par défaut)

Les formulaires passent quand même. Disponibilité > sécurité en cas de panne. Recommandé pour la plupart des sites.

CAPTCHACORE_FAIL_OPEN=true

Fail-Closed

Les formulaires sont bloqués si le service ne répond pas. Uniquement pour les systèmes hautement critiques.

CAPTCHACORE_FAIL_OPEN=false

Tous les appels API ont un timeout de 3 secondes. En cas de timeout, la configuration fail-open/closed s'applique.

Clés & rotation

Chaque site possède une paire de clés : la clé de site (publique, dans le navigateur) et la clé secrète (confidentielle, serveur uniquement).

Formats de clés

cc_pub_6e65b5c4597a688c93f3be6e345ee1a5...  ← 7 + 64 hex = 71 Zeichen
cc_sec_8bb043aa6424a1fdb3e048d2d3232894...  ← 7 + 64 hex = 71 Zeichen

Rotation des clés

Lors de la rotation, l'ancienne clé passe au statut rotated et reste valide encore 24 heures. Cela permet des rolling deployments sans interruption de service.

active — clé actuelle, utilisée pour les nouvelles requêtes
rotated — ancienne clé, encore valide 24 h (configurable)
revoked — immédiatement invalide, plus aucune requête possible

Sécurité de la clé secrète

  • La clé secrète est stockée en base de données sous forme de hash SHA-256
  • La clé en clair n'est affichée qu'une seule fois après sa création
  • Irrécupérable — en cas de perte : générer une nouvelle clé
  • N'apparaît jamais dans les logs, les réponses API ou les messages d'erreur

Exemples backend

L'endpoint verify peut être appelé depuis n'importe quel backend. Voici des exemples pour les langages courants :

PHP (sans framework)

$token = $_POST['captchacore_token'] ?? '';

$ch = curl_init('https://api.captchacore.eu/api/v2/verify');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 3,
    CURLOPT_HTTPHEADER     => [
        'X-CaptchaCore-Key: cc_sec_DEIN_SECRET',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'token'     => $token,
        'form_type' => 'contact',
    ]),
]);
$result = json_decode(curl_exec($ch), true);

if (!$result['valid']) {
    die('Bot erkannt.');
}

Node.js

const token = req.body.captchacore_token;

const res = await fetch('https://api.captchacore.eu/api/v2/verify', {
  method: 'POST',
  headers: {
    'X-CaptchaCore-Key': process.env.CAPTCHACORE_SECRET_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ token, form_type: 'register' }),
});
const { valid, risk_score, action } = await res.json();

if (!valid) return res.status(403).json({ error: 'Bot detected' });

Python

import requests

result = requests.post(
    'https://api.captchacore.eu/api/v2/verify',
    headers={'X-CaptchaCore-Key': 'cc_sec_DEIN_SECRET'},
    json={'token': token, 'form_type': 'login'},
    timeout=3,
).json()

if not result['valid']:
    raise Exception('CaptchaCore verification failed')

Infrastructure & domaines

Architecture de domaines

Domaine Finalité Type
api.captchacore.euChallenge, Verify, Status, VersionAPI (JSON)
src-eu.captchacore.euWidget JS + Worker (CDN EU uniquement)CDN (par défaut)
src.captchacore.euWidget JS + Worker (CDN mondial)CDN (optionnel)
captchacore.euSite web, panneau d'administration, docsFrontend

Content Security Policy (CSP)

Si vous utilisez une Content Security Policy sur votre site web, les domaines suivants doivent être autorisés :

# Minimal (EU-only CDN + API)
script-src  https://src-eu.captchacore.eu;
connect-src https://api.captchacore.eu https://src-eu.captchacore.eu;
worker-src  blob:;

# Mit globalem CDN (zusätzlich)
script-src  https://src.captchacore.eu;
connect-src https://src.captchacore.eu;

Pourquoi ces entrées ?

  • script-src — Le JS du widget (captchacore-v2.min.js) est chargé depuis le CDN
  • connect-src (API) — Le widget appelle /api/v2/challenge via fetch()
  • connect-src (CDN) — Le worker PoW est chargé depuis le CDN via fetch()
  • worker-src blob: — Le worker est instancié via une URL blob (évite le CORS)

En-têtes CORS

CaptchaCore définit automatiquement les bons en-têtes CORS sur tous les endpoints API. Vous n'avez aucune configuration CORS à effectuer de votre côté. L'API répond avec :

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Accept, X-CaptchaCore-Key

Exemple NGINX pour votre site web

Si vous avez configuré une CSP stricte sur votre site web :

# NGINX — CSP für CaptchaCore Widget
add_header Content-Security-Policy
  "script-src 'self' https://src-eu.captchacore.eu;
   connect-src 'self' https://api.captchacore.eu https://src-eu.captchacore.eu;
   worker-src 'self' blob:;"