# Le schéma data dans la Content Security Policy (/fr/blog/csp-data-scheme)



Le schéma `data:` permet à une URL de transporter son propre contenu en inline, si bien que `data:image/png;base64,...` constitue une image entière sans serveur à interroger. Dans une politique de sécurité du contenu (CSP), vous pouvez autoriser ce schéma directive par directive. Pour les images et les polices, c'est pratique et courant. Pour les scripts, cela offre à un attaquant un moyen d'exécuter du code sans aucun hôte externe.

Cet article montre où `data:` a sa place dans une politique, où il n'en a pas, et pourquoi la différence compte.

## À quoi ressemble le schéma data dans une CSP [#à-quoi-ressemble-le-schéma-data-dans-une-csp]

`data:` est une [source de schéma](/fr/docs/web-security/policies/content-security-policy/values/csp-scheme-source). La grammaire correspond au nom du schéma suivi de deux-points, donc vous écrivez `data:` tel quel, avec le deux-points final et sans guillemets, contrairement aux sources par mot-clé comme `'self'`.

L'usage courant et raisonnable concerne les images et les polices en inline :

```http
Content-Security-Policy: img-src 'self' data:; font-src 'self' data:
```

Cela autorise [`img-src`](/fr/docs/web-security/policies/content-security-policy/directives/img-src) et [`font-src`](/fr/docs/web-security/policies/content-security-policy/directives/font-src) à charger des ressources depuis votre propre origine et depuis des data URI en inline, ce qui permet l'affichage des icônes en base64, des petites images de remplacement et des polices embarquées.

Chaque directive est indépendante. Il n'y a pas de `data:` sur une directive tant que vous ne l'y écrivez pas, et il n'arrive ni par un fallback ni par un wildcard (nous y revenons plus bas).

## Pourquoi data est sûr pour les images mais dangereux pour les scripts [#pourquoi-data-est-sûr-pour-les-images-mais-dangereux-pour-les-scripts]

Une image `data:` ne peut pas exécuter de code. Ce sont des octets que le navigateur décode et peint. Un script `data:` est différent : l'URL transporte le corps du script, donc toute la charge utile voyage à l'intérieur de l'expression de source.

Si [`script-src`](/fr/docs/web-security/policies/content-security-policy/directives/script-src) autorise ce schéma, un attaquant capable d'injecter une seule balise `<script>` n'a besoin d'héberger quoi que ce soit. Le code passe directement dans l'URL :

```html
<script src="data:text/javascript,alert(document.domain)"></script>
<script src="data:;base64,YWxlcnQoMSk="></script>
```

Les versions actuelles de Chrome, Firefox et Safari exécutent les scripts `data:` externes, donc c'est un vecteur d'exécution opérationnel aujourd'hui, pas une bizarrerie héritée du passé. Les analyses de risque présentent `data:` dans `script-src` comme un contournement de CSP ; la spécification CSP elle-même ne définit que la correspondance des schémas et ne le signale pas comme un avertissement XSS, donc traitez ce danger comme un constat de durcissement plutôt que comme une règle de la spec.

Une distinction maintient l'honnêteté du propos. Les navigateurs bloquent la navigation de premier niveau vers une URL `data:`, un changement anti-phishing plus ancien, mais cela ne bloque pas les sous-ressources `data:` comme `<script src="data:...">` ou `<img src="data:...">`. Le script se charge en sous-ressource dans la propre origine de la page, donc le blocage de navigation ne s'applique pas.

## Le wildcard ne couvre pas data [#le-wildcard-ne-couvre-pas-data]

On suppose naturellement que `script-src *` autorise tout, y compris `data:`. Ce n'est pas le cas. En CSP Level 3, un simple `*` ne correspond à une URL que lorsque celle-ci utilise un schéma HTTP ou HTTPS (plus le même schéma que le document protégé). Les schémas `data:`, `blob:` et `filesystem:` sont exclus et doivent être listés explicitement.

```http
Content-Security-Policy: script-src *
```

Cette politique n'autorise pas les scripts `data:`. Il faudrait ajouter `data:` vous-même pour qu'ils s'exécutent, ce qui est précisément la raison pour laquelle vous ne devriez pas le faire.

Cette exclusion est un correctif de sécurité délibéré. Les navigateurs ont plus tard restreint la correspondance de `data:` après qu'un contournement réel via un wildcard s'est confirmé, et le comportement est cohérent entre les navigateurs actuels.

## Où autoriser data, et où ne pas le faire [#où-autoriser-data-et-où-ne-pas-le-faire]

Décidez directive par directive, selon que la directive peut ou non mener à l'exécution de code :

* [`img-src`](/fr/docs/web-security/policies/content-security-policy/directives/img-src), `font-src` et [`media-src`](/fr/docs/web-security/policies/content-security-policy/directives/media-src) : autoriser `data:` est légitime et très répandu pour les ressources en base64 en inline.
* [`script-src`](/fr/docs/web-security/policies/content-security-policy/directives/script-src) : n'autorisez pas `data:`. C'est un vecteur d'exécution XSS, comme montré plus haut.
* [`object-src`](/fr/docs/web-security/policies/content-security-policy/directives/object-src) et `frame-src` : risqués également, puisque des plugins ou des frames `data:` peuvent transporter du contenu actif.
* `style-src` : déconseillé. Une feuille de style `data:` contrôlée par un attaquant se charge comme une sous-ressource et s'applique, ce qui constitue un vrai vecteur d'injection et d'exfiltration basé sur CSS (mais pas d'exécution de code).
* [`default-src`](/fr/docs/web-security/policies/content-security-policy/directives/default-src) : particulièrement néfaste. En l'absence de `script-src`, c'est `default-src` qui régit les scripts, donc `default-src data:` permet de fait les scripts `data:`.

Une grande partie des sites autorisait historiquement `data:` sous `script-src`, `frame-src` ou `object-src` (ou `default-src` lorsque `script-src` était absent), et c'est pourquoi cela reste un constat fréquent.

## L'alternative plus sûre pour les scripts [#lalternative-plus-sûre-pour-les-scripts]

Le correctif n'est pas de trouver une manière prudente d'autoriser `data:` dans `script-src`. C'est de cesser complètement d'autoriser les scripts par schéma ou par hôte, et de les autoriser par [nonce ou hash](/fr/docs/web-security/policies/content-security-policy/values/csp-hashes-nonce) à la place, avec [`'strict-dynamic'`](/fr/blog/strict-dynamic-csp).

Les recommandations de Chrome et de Google sont explicites : les allowlists par hôte et par schéma offrent peu de protection, et un nonce ou un hash plus `'strict-dynamic'` est le modèle à adopter. Une politique stricte minimale ressemble à ceci :

```http
Content-Security-Policy: script-src 'nonce-r4nd0m' 'strict-dynamic';
    object-src 'none';
    base-uri 'none'
```

Avec un nonce en place, le navigateur ne fait confiance qu'aux scripts portant ce nonce et aux scripts que ces scripts de confiance chargent. Un script `data:` sans nonce correspondant est rejeté, donc le contournement se referme même si un attaquant injecte une balise. Pour l'argumentaire plus large contre l'ouverture de la politique de cette façon, voyez [pourquoi supprimer `'unsafe-inline'` compte](/fr/blog/unsafe-inline-csp) et la démonstration plus complète dans [comment construire une CSP solide](/fr/blog/how-to-build-a-strong-csp).

Si vous avez besoin de quelques images ou polices en base64 en inline, gardez `data:` cantonné à `img-src` et `font-src` et laissez-le hors de tout ce qui touche au script ou au style.

## Repérer data dans votre propre politique [#repérer-data-dans-votre-propre-politique]

Déployez les changements de la manière sûre : placez d'abord une politique candidate sur le header [`Content-Security-Policy-Report-Only`](/fr/docs/web-security/policies/content-security-policy/report-only), surveillez les reports, et n'appliquez la politique qu'une fois qu'ils sont silencieux. Pour voir où en est votre politique en production aujourd'hui, passez-la dans le [évaluateur CSP](/tools/csp-evaluator), qui signale `data:` dans `script-src` et d'autres sources faibles afin que vous sachiez quoi resserrer avant qu'elles ne deviennent une porte d'entrée.

L'évaluateur lit la politique que vous livrez déjà. Ce qu'il ne peut pas vous dire, c'est quelles URI `data:` vos pages chargent réellement, car cela n'apparaît qu'à l'exécution. CentralCSP collecte les reports csp-violation issus de vraies visites et les regroupe par URI bloquée, si bien qu'en retirant `data:` de `script-src` vous voyez exactement quels payloads inline cessent de se charger, et si certains étaient les vôtres.

## Articles liés [#articles-liés]

* [Le schéma blob dans la Content Security Policy](/fr/blog/csp-blob-scheme)
* [Pourquoi ne jamais utiliser unsafe-inline dans une CSP](/fr/blog/unsafe-inline-csp)
