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.0
l'é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
. SQL
L'injection est apparue plus tard , et SQL
l'émergence de l'injection est Web
une étape importante dans l'histoire de la sécurité.Les SQL
vulnérabilités d'injection sont toujours Web
une 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.0
la montée en puissance de , des attaques telles que XSS
, CSRF
et , sont devenues plus puissantes. Web
L'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.
Web
Avec 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
, , NodeJS
etc. 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 5
de nouvelles opportunités et de nouveaux défis. Dans le même temps, Web
la 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 10
Les menaces ont été répertoriées à plusieurs reprises XSS
en haut de la liste, et cet article se concentrera sur XSS
les 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 CSS
des feuilles de style en cascade ( Cascading Style Sheet
, ), elle est appelée " " dans le champ de sécurité.CSS
XSS
XSS
Une attaque fait généralement référence à un comportement d'attaque dans lequel un pirate HTML
injecte 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 Web
la complexité des fonctions et de l'application du terminal, peu importe qu'il soit intersite, mais XSS
le nom a été conservé.
Avec Web
le développement rapide du développement, Web
le développement a été largement utilisé, de l' PC
extré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.
XSS
Classement des types d'attaques
XSS
Les 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 XSS
est aussi appelé "non persistant **XSS**
" ( **Non-persistent XSS**
) .
Il existe généralement XSS
un code malveillant réfléchissant URL
, via URL
la 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 URL
pour 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 localStorage
peuvent être facilement obtenues, ce qui lui permet d'obtenir des informations critiques.
Type de stockage
Le type de stockage XSS
va "stocker" les données saisies par l'utilisateur côté serveur. C'est XSS
très stable.
Un scénario relativement courant est qu'un pirate rédige un JavaScript
article 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 JavaScript
code malveillant dans leur navigateur. Les pirates enregistrent des scripts malveillants sur le serveur, ce type d' XSS
attaque 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
alert
Lorsque l'utilisateur navigue sur la page, la pop-up box se déclenche et les données locales sont obtenues successivement localStorage
:
Ce qui précède est une attaque de stockage typique .
basé surDOM XSS
En fait, ce type XSS
n'est pas divisé selon "si les données sont stockées côté serveur", DOM Based XSS
mais il est également réfléchissant en effet XSS
. Il est divisé séparément car DOM Based XSS
la 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 型 XSS
La différence avec les deux précédents XSS
est que DOM 型 XSS
lors de l'attaque, l'extraction et l'exécution de code malveillant sont effectuées par le navigateur, ce qui est une JavaScript
faille de sécurité du front-end lui-même, tandis que les deux autres XSS
sont 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 href
l'attribut et à lui donner une valeur nulle. Cliquez ensuite sur 提交内容
le bouton, le libellé de la page <div id="div"></div>
contient le html
contenu suivant
<a href onlick="alert(/xss/)">链接地址</a>
XSS
défense d'attaque
La défense XSS
est 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
HttpOnly
Il a d'abord été proposé par Microsoft et IE 6
implémenté en Chine, et est progressivement devenu un standard. Les navigateurs interdiront JavaScript
l'accès aux pages avec HttpOnly
des attributs Cookie
. Nous devons donc le définir dans http
l'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-cookie
httpOnly
document.cookie
cookie
À proprement parler, HttpOnly
ce n'est pas pour contrer l'attaque de piratage post- XSS——HttpOnly
résolution . Son utilisation permet donc d'atténuer l'attaque, mais nécessite toujours d'autres solutions capables de résoudre la vulnérabilité.XSS
Cookie
HttpOnly
XSS
XSS
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 XSS
termes 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,"&")
.replace(/</g,"<")
.replace(/>/g,">")
.replace(/ /g," ")
.replace(/\'/g,"'")
.replace(/\"/g,""");
}
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 deviendra3 < 4
. Lorsque cette valeur est enregistrée à l'extrémité distante, elle seraAJAX
obtenue 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 HTML
la page, l'encodage ou l'échappement peuvent être utilisés pour se défendre contre XSS
les 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. HTML
Sortie 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. HTML
Sortie 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-name
un 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. CSS
Sortie en
Les manières de former dans et CSS
, style
sont 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 attribute
XSS
<style>
HTML
style
CSS
la défenseDOM Based XSS
DOM Based XSS
Il s'agit d'un type particulier de XSS
vulné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/React
la pile technologique et n'utilisez pas v-html
la fonction / dangerouslySetInnerHTML
, vous devez éviter les dangers cachés de 、 au render
niveau du front-end . Il y aura un paragraphe dédié à la défense à ce sujet plus tard.innerHTML
outerHTML
XSS
Vue
XSS
De nombreux endroits seront déclenchés DOM Based XSS
et les endroits suivants sont le seul moyen JavaScript
de sortir sur HTML
la 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.
Vue
XSS
défense dans
Vue
Si vous l'utilisez comme framework de développement frontal dans votre projet , félicitations, Vue
il résoudra la plupart des XSS
problèmes d'attaque pour vous, mais Vue
ce n'est pas un XSS
framework pour la prévention des attaques, et il y a encore des vulnérabilités à attaquer pendant le développement et l'utilisation ;
Vue
mesures défensives dans
Indépendamment de l'utilisation d'un modèle ou d'une fonction de rendu, Vue
le 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 html
est le suivant :
<p>
<script>alert('xss')</script>
</p>
La raison est Vue
de 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 :
<script>alert("xss")</script>
injectionHTML
Si vous souhaitez injecter dynamiquement HTML
du 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 userProvidedHtml
contenu des données distantes afin d'assurer la sécurité ;
// 一个简单的函数,通过转义<为<以及>为>来实现防御HTML节点内容
const escape = function(str){
return str.replace(/</g, '<').replace(/>/g, '>')
}
injection de style
Utilisez Vue
la 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 CSS
l'"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 property
des 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
, JavaScript
ou même CSS
), vous pouvez vous mettre en position d'être attaqué. Ces suggestions sont en fait vraies, que vous utilisiez Vue
, React
un autre framework ou même aucun framework.