Fermer

octobre 31, 2018

Sur la stratégie de script intersite et de sécurité du contenu


Avez-vous envisagé la sécurité de votre application ce mois-ci? Voici quelques conseils de sécurité pour vous protéger des pirates informatiques et éviter les surprises fantasmagoriques.

Octobre est le mois du Mois national de sensibilisation à la cybersécurité . C'est donc un excellent prétexte pour parler de l'un des plus courants. types d'attaques dirigées contre les applications Web, Cross-Site Scripting et comment l'atténuer à l'aide d'une fonction de sécurité présente dans tous les navigateurs modernes appelée Politique de sécurité du contenu .

Script intersite

Le script inter-sites ou XSS en abrégé, est l'un des problèmes de sécurité les plus courants dans les applications Web de nos jours. Dans XSS, un attaquant parvient à injecter son propre code dans notre application. Ce code sera ensuite exécuté lorsque les utilisateurs visitent la page, ce qui lui permet de voler des cookies ou de consigner toutes les pressions de touche.

Pour en faire la démonstration, nous avons construit une petite application avec un formulaire qui est vulnérable à l'XSS . L'application fonctionne correctement: nous entrons du texte dans l'élément textarea puis appuyez sur le bouton Soumettre et notre commentaire est ajouté à la liste. Cependant, remarquez ce qui se passe lorsque nous saisissons du code HTML sur le terrain, comme React est génial ! :

 Réagissez est génial-1 "title =" Réagissez est génial- 1 "/> </p>
<p> <img decoding=:

 Réagir est génial piraté-1 "title =" Réagir est génial piraté-1 " /> </p>
<p> <img decoding= OWASP XSS .) en tant qu'enfants d'un élément. Si nous voulons vraiment restituer du HTML non échappé, nous devons utiliser un accessoire spécial nommé dangereusementSetInnerHTML :

export default classe ListOfComments: extension React.Component {. render () {

const {comments} = ce .props;

return (

    {comments.map ((comment) => (19459015]

    <1965 li

    clé = {commentaire}

    dangereusement SetInnerHTML = {{__html: comment}}

    />

    )}}

]

}

Bien qu'il existe des cas d'utilisation valables pour dangereusementSetInnerHTML tels que le rendu du code HTML assaini provenant de votre serveur, j'essayais de minimiser son utilisation, car il est très facile de faire quelque chose de mal et de s’ouvrir à une attaque.

Politique de sécurité du contenu

Le problème qui sous-tend une attaque XSS est que le navigateur ne sait pas à quelles sources de code faire confiance. Ma balise et votre balise injectée sont toutes les deux valides, le navigateur les exécutera donc toutes.

La politique de sécurité du contenu est une fonctionnalité de sécurité présente dans tous les navigateurs modernes qui nous permet de répertorier quelles sources sont approuvées par notre application Web, afin que le navigateur puisse bloquer tout le reste. Si votre nom figure sur la liste des invités, vous pouvez participer à la fête. sinon, vous restez à l'extérieur.

Il existe deux façons de déclarer une stratégie de sécurité du contenu: via un en-tête HTTP Content-Security-Policy lors du traitement de votre page HTML et via un tag . .

Dans notre exemple d'application, nous n'avons pas le contrôle sur les en-têtes HTTP, nous allons donc utiliser une balise . Ajoutons la politique de sécurité du contenu la plus restrictive possible, par défaut, src 'none' qui indique en gros au navigateur de ne faire confiance à aucune source, et voyons ce qui se passe:

[19659002] < html >

tête >

[19659000] < meta http-equiv = "Politique de sécurité du contenu"

] content = "default-src 'none'" />

/

</ head >

</ <19659022] corps >

</ body >

<1945 html >

Eh bien, tout semble cassé:

 Erreurs de stratégie de sécurité du contenu "title =" Erreurs de stratégie de sécurité du contenu "/> </p>
<p> Les messages d'erreur sont quelque peu cryptiques, mais nous pouvons les comprendre en cherchant dans l'article <a href= Content Security Policy de MDN qui décrit toutes les directives et valeurs possibles que nous pouvons spécifier.

Passons un à un.

Fixing Script Erreurs

La première erreur concerne les scripts bloqués:

Refuse d'évaluer une chaîne en tant que JavaScript, car 'unsafe-eval' n'est pas une source de script autorisée dans la directive suivante relative à la politique de sécurité du contenu: “default-src 'aucun'". Notez que 'script-src' n'a pas été défini explicitement, donc 'default-src' est utilisé comme solution de secours.

Nous n'avons pas fourni de stratégie script-src le navigateur est donc retourné à ce qui est spécifié comme default-src (qui est 'aucun' ) et a refusé de charger tous les scripts. Il semble que les personnes hébergeant notre exemple d'application, StackBlitz exécutent notre code via eval nous devrons donc l'autoriser en tant que source dans notre script [src directive:

< meta http-equiv = "Politique de sécurité du contenu"

 contenu [19659029] = </code><code style= "default-src 'none'; script-src 'unsafe-eval'" />

(Notez que vous ne voudriez pas faire cela dans une application réelle. Permettre à aucun des le unsafe - * des sources comme unsafe-eval ou unsafe-inline est probablement une très mauvaise idée!)

Correction des erreurs de style

La deuxième erreur concerne le blocage des styles:

a refusé de charger la feuille de style 'https://cdn.jsdelivr.net/npm/@progress/kendo-theme-default@latest/dist/all.css' car elle enfreint la directive suivante sur la politique de sécurité du contenu: «default-src none » ». Notez que 'style-src' n'a pas été défini explicitement, donc 'default-src' est utilisé comme solution de secours.

De même, nous n'avons pas fourni de stratégie style-src de sorte que le navigateur est retombé à de défaut-src et a refusé de charger tous les styles. Nous pouvons spécifier le chemin exact de la feuille de style, un chemin partiel ou simplement le domaine. Nous spécifierons ici un chemin partiel, de sorte que tous les styles provenant de paquets à l'origine @progress soient approuvés:

< meta http-equiv = "Content-Security-Policy"

Correction des erreurs de police

Les dernières erreurs concernent le blocage des polices:

A refusé de charger la police 'data: font / ttf; base64,…' car elle constitue une violation de la directive suivante relative à la politique de sécurité du contenu: «default-src 'none'». Notez que 'font-src' n'a pas été défini explicitement, donc 'default-src' est utilisé comme solution de secours.

Le fichier CSS ci-dessus semble inclure des polices codées en base64 à l'aide du protocole : , nous devrons donc ajouter une directive font-src qui autorise cela:

< meta http-equiv = "Content-Security- Politique "

Trial by Fire

Maintenant, l'application fonctionne à nouveau! Essayons notre attaque initiale en injectant dans la page:

 Réagissez est génial sécurisé "title =" Réagissez est génial sécurisé "/> </p>
<p> CSP a bloqué l'attaque! Voici le message d'erreur que nous avons reçu: </p>
<blockquote>
<p> Refuse d'exécuter le gestionnaire d'événements inline car il enfreint la directive suivante relative à la politique de sécurité du contenu: "script-src 'unsafe-eval" ". Soit le mot clé" unsafe-inline ", un hachage (" sha256-… "), ou un nonce ('nonce-…') est requis pour permettre l'exécution en ligne. </p>
</blockquote>
<p> Nous n'autorisions pas les scripts en ligne en tant que source approuvée; le navigateur a donc empêché le code de s'exécuter. 1965 </p>
<h2> Mode Report-Only </h2>
<p> D'accord, c'est vraiment cool, mais je ne vais absolument pas ajouter de politique de sécurité du contenu à mon application! Et si je la configurais mal et que je casse une fonctionnalité importante pour mes utilisateurs? </p>
<p> derrière la spécification CSP doit avoir pensé à ce scénario exact. Ils ont ajouté un mode de rapport uniquement qui générera des erreurs au c Si nous devions ajouter cette balise à notre application: </p>
<div class=

< meta http-equiv = "Contenu-Sécurité-Politique-Rapport-Seulement "

content = " default-src 'none' " />

nous verrions toutes les violations du CSP se dérouler dans le

Nous pouvons aller encore plus loin et utiliser la directive report-uri pour demander au navigateur d'envoyer toutes les violations à un terminal placé sous notre contrôle, afin que nous pouvons les regrouper dans un tableau de bord ou quelque chose du genre:

< meta http-equiv = "Contenu-Sécurité-Politique-Rapport-Seulement"

content = "default-src 'none'; report-uri / api / csp " />

Chaque fois que le navigateur rencontre une violation de notre CSP, il fera une demande POST à / api / csp avec contenu qui ressemble à ceci:

{

"csp-report": {

"referrer": "", [1945925]. ]

"directive violée": "img-src",

"directive-effective": " img-src ",

" politique-originale ":" défaut-src 'aucune'; report-uri / api / csp ",

" disposition ":" rapport ",

" statut-code ": 0,

"script-sample": ""






Source link