Série sur la sécurité frontale Web : attaque et défense XSS

Préface L'essor de la sécurité Web

Le développement de la technologie d'attaque Web peut également être divisé en plusieurs étapes. À Web 1.0l'époque, les gens accordent plus d'attention aux
problèmes de sécurité des scripts dynamiques côté serveur, tels que le téléchargement d'un script exécutable (communément appelé webshell) sur le serveur pour obtenir des autorisations
. SQLL'injection est apparue plus tard , et SQLl'émergence de l'injection est Webune étape importante dans l'histoire de la sécurité.Les SQLvulnérabilités d'injection sont toujours Webune partie importante du domaine de la sécurité. Suivi d'un autre problème de sécurité marquant - XSS(attaque de script intersite). Avec Web 2.0la montée en puissance de , des attaques telles que XSS, CSRFet , sont devenues plus puissantes. WebL'idée d'attaque s'est également déplacée du côté serveur vers le côté client, vers le navigateur et l'utilisateur.

WebAvec le développement de la technologie aujourd'hui, un Internet riche et coloré a été construit. Le développement vigoureux de l'activité Internet a également donné naissance à
de nombreux langages de script émergents, tels que Python, Ruby, , NodeJSetc. Le développement agile est devenu le thème principal d'Internet. L'essor de la technologie de la téléphonie mobile et de l'Internet mobile a également apporté HTML 5de nouvelles opportunités et de nouveaux défis. Dans le même temps, Webla technologie de sécurité suivra également le rythme du développement d'Internet et évoluera constamment avec de nouveaux changements.

Les attaques de script intersite ( XSS) sont l'ennemi numéro un de la sécurité des scripts côté client. OWASP TOP 10Les menaces ont été répertoriées à plusieurs reprises XSS
en haut de la liste, et cet article se concentrera sur XSSles problèmes offensifs et défensifs

Exploration préliminaireXSS

Attaque de script intersite , le nom anglais complet est Cross Site Script, l'abréviation d'origine est , mais afin de la distinguer CSSdes feuilles de style en cascade ( Cascading Style Sheet, ), elle est appelée " " dans le champ de sécurité.CSSXSS

XSSUne attaque fait généralement référence à un comportement d'attaque dans lequel un pirate HTMLinjecte des pages Web falsifiées et insère des scripts malveillants pour contrôler le navigateur de l'utilisateur lorsque celui-ci navigue sur le Web. Lorsque ce comportement est apparu pour la première fois, tous les cas de démonstration étaient des comportements inter-domaines, il s'appelait donc "script inter-site". Aujourd'hui, avec Webla complexité des fonctions et de l'application du terminal, peu importe qu'il soit intersite, mais XSSle nom a été conservé.

Avec Weble développement rapide du développement, Weble développement a été largement utilisé, de l' PCextrémité unique précédente à l'extrémité mobile actuelle ( APP, H5), incluant même des outils de bureau, de grands écrans d'équipement, etc., de sorte que les scénarios d'application générés deviennent de plus en plus Les situations sont nombreuses, de plus en plus complexes, et parallèlement, le temps de lancement itératif de la plupart des versions de développement de produits Internet (industries traditionnelles notamment) est très court, dans le cas d'une version par semaine et d'une grosse version en deux semaines , l'attribut important de la sécurité est ignoré. Une fois attaqué, les conséquences seront désastreuses.

XSSClassement des types d'attaques

XSSLes attaques peuvent être divisées en trois catégories : réflexives (non persistantes), de stockage (persistantes) et basées surDOM XSS ;

réfléchissant

Le type réfléchissant XSS"reflète" simplement les données saisies par l'utilisateur dans le navigateur. En d'autres termes, les pirates ont souvent besoin d'inciter les utilisateurs à "cliquer" sur un lien malveillant pour réussir leur attaque. Le type réfléchissant XSSest aussi appelé "non persistant **XSS**" ( **Non-persistent XSS**) .

Il existe généralement XSSun code malveillant réfléchissant URL, via URLla fonction de transmission de paramètres, tels que la recherche de sites Web, le saut, etc. Étant donné que l'utilisateur doit ouvrir activement le site Web malveillant URLpour prendre effet, les attaquants combinent souvent diverses méthodes pour inciter les utilisateurs à cliquer.

L'une des attaques par réflexion les plus élémentaires est : nous obtenons des données de page Web :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XSS攻防演练</title>
</head>
<body>
    <div id="t"></div>
    <input id="s" type="button" value="这是一个按钮" onclick="test()">
</body>
<script>
    function test() {
      
      
        const arr = ['自定义的数据1', '自定义的数据2', '自定义的数据3', '<img src="11" οnerrοr="console.log(window.localStorage)" />']
        const t = document.querySelector('#t')
            arr.forEach(item => {
      
      
            const p = document.createElement('p')
            p.innerHTML = item
            t.append(p)
        })
    }
</script>
</html>

Lorsqu'un pirate clique sur 这是一个按钮, des données locales localStoragepeuvent être facilement obtenues, ce qui lui permet d'obtenir des informations critiques.

Type de stockage

Le type de stockage XSSva "stocker" les données saisies par l'utilisateur côté serveur. C'est XSStrès stable.

Un scénario relativement courant est qu'un pirate rédige un JavaScriptarticle de blog contenant du code malveillant. Après la publication de l'article, tous les utilisateurs qui visitent l'article de blog exécuteront ce JavaScriptcode malveillant dans leur navigateur. Les pirates enregistrent des scripts malveillants sur le serveur, ce type d' XSSattaque est donc appelé "type de stockage **XSS**" .

<!-- 例如我们分别在网站中的输入框中输入以下信息,并保存到远程数据库 -->
<img src="11" onerror="console.log(window.localStorage)" />
<img src="11" onerror="alert(111)" />

entrée de page
insérez la description de l'image ici

insérez la description de l'image ici

alertLorsque l'utilisateur navigue sur la page, la pop-up box se déclenche et les données locales sont obtenues successivement localStorage:
insérez la description de l'image ici
insérez la description de l'image ici

Ce qui précède est une attaque de stockage typique .

basé surDOM XSS

En fait, ce type XSSn'est pas divisé selon "si les données sont stockées côté serveur", DOM Based XSSmais il est également réfléchissant en effet XSS. Il est divisé séparément car DOM Based XSSla raison de sa formation est assez particulière, et les experts en sécurité qui l'ont découvert ont spécifiquement proposé ce type XSS. DOM 型 XSSLa différence avec les deux précédents XSSest que DOM 型 XSSlors de l'attaque, l'extraction et l'exécution de code malveillant sont effectuées par le navigateur, ce qui est une JavaScriptfaille de sécurité du front-end lui-même, tandis que les deux autres XSSsont des failles de sécurité du serveur.

Prenons un exemple simple :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XSS攻防演练</title>
</head>
<body>
    <h3>基于DOM的XSS</h3>
    <input type="text" id="input">
    <button id="btn">提交内容</button>
    <div id="div"></div>
</body>
<script>
    const input = document.getElementById('input');
    const btn = document.getElementById('btn');
    const div = document.getElementById('div');

    let inputValue;
     
    input.addEventListener('change', (e) => {
      
      
        inputValue = e.target.value;
    }, false);

    btn.addEventListener('click', () => {
      
      
        div.innerHTML = `<a href=${ 
        inputValue}>链接地址</a>`
    }, false);
</script>
</html>

Nous entrons le texte suivant dans la zone de saisie de la page '' onclick=alert(/xss/). Les guillemets ici ''servent à fermer hrefl'attribut et à lui donner une valeur nulle. Cliquez ensuite sur 提交内容le bouton, le libellé de la page <div id="div"></div>contient le htmlcontenu suivant

<a href onlick="alert(/xss/)">链接地址</a>

insérez la description de l'image ici

XSSdéfense d'attaque

La défense XSSest très compliquée Heureusement, les navigateurs modernes et les frameworks/bibliothèques frontaux ont déjà fait une partie considérable du travail pour nous.

HttpOnly

HttpOnlyIl a d'abord été proposé par Microsoft et IE 6implémenté en Chine, et est progressivement devenu un standard. Les navigateurs interdiront JavaScriptl'accès aux pages avec HttpOnlydes attributs Cookie. Nous devons donc le définir dans httpl'en-tête de la réponse pour informer le navigateur que le contenu ne peut pas être obtenu par d'autres méthodes .set-cookiehttpOnlydocument.cookiecookie

À proprement parler, HttpOnlyce n'est pas pour contrer l'attaque de piratage post- XSS——HttpOnlyrésolution . Son utilisation permet donc d'atténuer l'attaque, mais nécessite toujours d'autres solutions capables de résoudre la vulnérabilité.XSSCookieHttpOnlyXSSXSS

vérification des entrées

Nous devons être sceptiques quant à la contribution des utilisateurs. L'utilisateur peut entrer n'importe quelle chaîne sans effectuer de vérification de filtrage sur l'entrée. Par exemple, le contenu que nous nous attendons à saisir est : hello word, peut-être que le contenu que nous avons reçu est onclick=alert(/xss/).

En XSStermes de défense, les contrôles de saisie vérifient généralement si les données saisies par l'utilisateur contiennent des caractères spéciaux, tels que <、>、’、”etc. Si des caractères spéciaux sont trouvés, ces caractères sont filtrés ou encodés. Cette méthode de vérification des entrées peut être appelée “XSS Filter”. Il existe de nombreuses “XSS Filter”implémentations open source sur Internet. Par exemple, un simple htmlencodeéchappement :

const htmlEncode = function (handleString){
    
    
    return handleString
    .replace(/&/g,"&amp;")
    .replace(/</g,"&lt;")
    .replace(/>/g,"&gt;")
    .replace(/ /g,"&nbsp;")
    .replace(/\'/g,"&#39;")
    .replace(/\"/g,"&quot;");
}

Mais la vérification des entrées présente également des inconvénients, tels que

  • L'attaquant contourne la page frontale et utilise directement l'interface pour envoyer du code malveillant à la bibliothèque distante.
  • Les données d'entrée peuvent également être affichées à plusieurs endroits et le contexte de chaque endroit peut être différent. Si une seule opération de remplacement est utilisée, des problèmes peuvent survenir. La vérification des entrées doit également être ciblée. Si nous voulons exprimer qu'un nombre est plus petit que l'autre ( 3 < 4), le caractère après l'échappement frontal deviendra 3 &lt; 4. Lorsque cette valeur est enregistrée à l'extrémité distante, elle sera AJAXobtenue et utilisé Cela causera des problèmes inutiles, par exemple, je vais effectuer des calculs numériques et ainsi de suite.

contrôle de sortie

D'une manière générale, en plus de la sortie de texte enrichi, lorsque des variables sont sorties sur HTMLla page, l'encodage ou l'échappement peuvent être utilisés pour se défendre contre XSSles attaques.

L'essence de XSS est toujours une sorte "d'injection HTML". Les données de l'utilisateur sont exécutées dans le cadre du code HTML, confondant ainsi la sémantique d'origine et générant une nouvelle sémantique.

Comme pour les contrôles d'entrée, nous pouvons encoder-échapper la sortie.

1. HTMLSortie en

Par exemple, il y a un tel morceau de code dans notre code html :

<div>$htmlVar</div>
<a href="">$htmlVar</a>

Si les variables de sortie ne sont pas traitées en toute sécurité, elles peuvent être directement utilisées et rendues sur la page, ce qui peut conduire à une génération directe XSS. Le résultat final peut générer le code suivant :

<div><script>alert('我是一个XSS攻击者')</script></div>
<a href="#"><img href="" onclick="alert('我是另外一个XSS攻击者')"></a>

La façon d'éviter cela est d'effectuer des contrôles d'échappement sur html

2. HTMLSortie dans les propriétés

Si notre attribut html est une valeur dynamique, alors l'attribut exploit peut également être attaqué ;

<div id="testXSS" data-name=""></div>

Insérez maintenant data-nameun code non échappé dans l'attribut "><script>alert('我是一个XSS攻击者')</script><", le résultat est le suivant :

<div id="testXSS" data-name=""><script>alert('我是一个XSS攻击者')</script><""></div>

3. <script>Sortie dans l'étiquette

Lors de la sortie dans <script>des balises, vous devez d'abord vous assurer que les variables de sortie sont entre guillemets.

<script>
  // 假设userData是攻击者注入的数据
  let xssVar = userData;
</script>

L'attaquant doit d'abord fermer les guillemets pour mettre en œuvre l'attaque XSS :

<script>
  // 假设userData是攻击者注入的数据
  let xssVar = "";alert('我是一个script XSS攻击者');
</script>

4. CSSSortie en

Les manières de former dans et CSS, stylesont très diverses, donc, en général, autant que possible, la sortie de variables contrôlables par l'utilisateur dans " étiquettes ", " attributs d'étiquettes " et " fichiers " est interdite. S'il doit y avoir une telle exigence, il est recommandé d'utiliser une bibliothèque d'échappement CSS.style attributeXSS<style>HTMLstyleCSS

la défenseDOM Based XSS

DOM Based XSSIl s'agit d'un type particulier de XSSvulnérabilité. Les différentes méthodes de défense mentionnées ci-dessus ne sont pas applicables et nécessitent un traitement spécial. Essentiellement, c'est en fait que le code JavaScript frontal du site Web n'est pas assez rigoureux et que des données non fiables sont exécutées en tant que code.

Si vous utilisez Vue/Reactla pile technologique et n'utilisez pas v-htmlla fonction / dangerouslySetInnerHTML, vous devez éviter les dangers cachés de 、 au renderniveau du front-end . Il y aura un paragraphe dédié à la défense à ce sujet plus tard.innerHTMLouterHTMLXSSVueXSS

De nombreux endroits seront déclenchés DOM Based XSSet les endroits suivants sont le seul moyen JavaScriptde sortir sur HTMLla page.

  • document.write();
  • document.writeln();
  • xxx.innerHTML();
  • xxx.outerHTML();
  • xxx.innerHTML.replace();
  • document.attachEvent();
  • window.attachEvent();
  • window.location();
  • window.name;

Par conséquent, les développeurs doivent se concentrer sur la question de savoir si les paramètres de ces endroits peuvent être contrôlés par les utilisateurs. Si ceux-ci sont utilisés dans le projet, assurez-vous d'éviter de coller des données non fiables dans la chaîne.

VueXSSdéfense dans

VueSi vous l'utilisez comme framework de développement frontal dans votre projet , félicitations, Vueil résoudra la plupart des XSSproblèmes d'attaque pour vous, mais Vuece n'est pas un XSSframework pour la prévention des attaques, et il y a encore des vulnérabilités à attaquer pendant le développement et l'utilisation ;

Vuemesures défensives dans

Indépendamment de l'utilisation d'un modèle ou d'une fonction de rendu, Vuele contenu interpolé sera automatiquement échappé, tout comme le code de modèle suivant :

<template>
    <p>{
   
   {userData}}</p>
</template>

<script>
    // 从远程获取的数据
    userData = "<script>alert('xss')</script>"
</script>

Le contenu du code source affiché sur la page après la compilation finale htmlest le suivant :

<p>
    <script>alert('xss')</script>
</p>

La raison est Vuede nous aider à échapper aux données, évitant ainsi l'injection de script. Cet échappement se fait via des API natives du navigateur telles que textContent, donc à moins qu'il n'y ait une faille de sécurité dans le navigateur lui-même, il n'y a pas de faille de sécurité. Le contenu échappé est le suivant :

&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;

injectionHTML

Si vous souhaitez injecter dynamiquement HTMLdu contenu distant, vous devez d'abord vous assurer que le contenu est sûr et valide, sinon vous devez prendre des mesures défensives pour filtrer ou échapper certains symboles de balise dangereux ; par exemple, vous pouvez afficher le rendu comme ceciHTML :

<!-- 当使用模版时 -->
<div v-html="userProvidedHtml"></div>

<!-- 当使用渲染函数时 -->
<script>
    h('div', {
      
      
    domProps: {
      
      
        innerHTML: this.userProvidedHtml
    }
    })
</script>
<!-- 当使用JSX 的渲染函数时 -->
<div domPropsInnerHTML={this.userProvidedHtml}></div>

Par exemple, nous pouvons utiliser une méthode simple (ou nous référer à une bibliothèque/plug-in XSS plus robuste pour filtrer le userProvidedHtmlcontenu des données distantes afin d'assurer la sécurité ;

// 一个简单的函数,通过转义<为&lt以及>为&gt来实现防御HTML节点内容
const escape = function(str){
    
    
    return str.replace(/</g, '&lt;').replace(/>/g, '&gt;')
}

injection de style

Utilisez Vuela balise Pour éviter le rendu à l'intérieur du modèle style:

<style>{
      
      {
      
       userProvidedStyles }}</style>

En effet, une fois passé userProvidedStyles, un utilisateur malveillant peut toujours fournir CSSl'"arnaque au clic", par exemple en stylisant le lien sous la forme d'une boîte transparente recouvrant le bouton "Connexion". Ensuite, https://user-XSS-website.com/faites en sorte qu'elle ressemble à la page de connexion de votre application, ils peuvent obtenir les véritables informations de connexion d'un utilisateur. Vue recommande donc d'utiliser 对象语法et d'autoriser uniquement les utilisateurs à fournir propertydes valeurs spécifiques pouvant être contrôlées en toute sécurité :

<!-- sanitizedUrl应为受控的地址 -->
<a
  v-bind:href="sanitizedUrl"
  v-bind:style="{
    color: userProvidedColor,
    background: userProvidedBackground
  }"
>
  click me
</a>

Il n'y a "pas de solution miracle" pour les problèmes de sécurité

Dans le processus de résolution des problèmes de sécurité, il est impossible de le faire une fois pour toutes, c'est-à-dire "il n'y a pas de solution miracle".

D'une manière générale, les gens détestent les choses gênantes et espèrent inconsciemment que le problème peut être tenu aussi loin que possible. Et la sécurité est une chose gênante, et c'est un problème inévitable. Quiconque veut résoudre le problème de sécurité une fois pour toutes est un vœu pieux. Il est irréaliste de "se tromper".

Les meilleures pratiques

La règle générale est que tant que vous autorisez l'exécution de contenu non filtré fourni par l'utilisateur (que ce soit comme HTML, JavaScriptou même CSS), vous pouvez vous mettre en position d'être attaqué. Ces suggestions sont en fait vraies, que vous utilisiez Vue, Reactun autre framework ou même aucun framework.

les références

Je suppose que tu aimes

Origine blog.csdn.net/gaojinbo0531/article/details/129416340
conseillé
Classement