J'ai lu ceci sur le React tutoriel. Qu'est-ce que cela signifie?
React est sûr. Nous ne générons pas de chaînes HTML, la protection XSS est donc la protection par défaut.
Comment fonctionnent les attaques XSS si React est sans danger? Comment cette sécurité est-elle obtenue?
ReactJS est assez sûr par conception depuis
donc une attaque typique comme celle-ci ne fonctionnera pas
const username = "<img onerror='alert(\"Hacked!\")' src='invalid-image' />";
class UserProfilePage extends React.Component {
render() {
return (
<h1> Hello {username}!</h1>
);
}
}
ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
mais ...
dangerouslySetInnerHTML
Lorsque vous utilisez dangerouslySetInnerHTML
, vous devez vous assurer que le contenu ne contient pas de javascript. React ne peut rien faire ici pour vous.
const aboutUserText = "<img onerror='alert(\"Hacked!\");' src='invalid-image' />";
class AboutUserComponent extends React.Component {
render() {
return (
<div dangerouslySetInnerHTML={{"__html": aboutUserText}} />
);
}
}
ReactDOM.render(<AboutUserComponent />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Exemple 1: Utilisation de javascript: code
Cliquez sur "Lancer l'extrait de code" -> "Mon site Web" pour voir le résultat.
const userWebsite = "javascript:alert('Hacked!');";
class UserProfilePage extends React.Component {
render() {
return (
<a href={userWebsite}>My Website</a>
)
}
}
ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Exemple 2: Utilisation de données codées en base64:
Cliquez sur "Lancer l'extrait de code" -> "Mon site Web" pour voir le résultat.
const userWebsite = "data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGFja2VkISIpOzwvc2NyaXB0Pg==";
class UserProfilePage extends React.Component {
render() {
const url = userWebsite.replace(/^(javascript\:)/, "");
return (
<a href={url}>My Website</a>
)
}
}
ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
const customPropsControledByAttacker = {
dangerouslySetInnerHTML: {
"__html": "<img onerror='alert(\"Hacked!\");' src='invalid-image' />"
}
};
class Divider extends React.Component {
render() {
return (
<div {...customPropsControledByAttacker} />
);
}
}
ReactDOM.render(<Divider />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Voici plus de ressources
React échappe automatiquement aux variables pour vous ... Cela empêche l'injection de XSS via une chaîne HTML avec du code Javascript malveillant. Naturellement, les entrées sont également nettoyées.
Par exemple, disons que vous avez cette chaîne
var htmlString = '<img src="javascript:alert('XSS!')" />';
si vous essayez de rendre cette chaîne en réaction
render() {
return (
<div>{htmlString}</div>
);
}
vous verrez littéralement sur la page toute la chaîne, y compris la balise de l'élément <span>
. aka dans le navigateur, vous verrez <img src="javascript:alert('XSS!')" />
si vous visualisez le code HTML source, vous verriez
<span>"<img src="javascript:alert('XSS!')" />"</span>
Voici quelques détails supplémentaires sur ce qu'est une attaque XSS
React permet de faire en sorte que vous ne puissiez pas insérer de balisage à moins de créer vous-même les éléments dans la fonction de rendu. Cela dit, ils ont une fonction qui permet un tel rendu appelé dangerouslySetInnerHTML
... voici quelques détails supplémentaires à ce sujet
Peu de choses à noter, il existe des moyens de contourner ce que React échappe. Un autre moyen courant consiste à définir les accessoires pour votre composant. Ne prolongez pas les données de la saisie de l'utilisateur comme accessoires!