web-dev-qa-db-fra.com

Qu'est-ce que cela signifie quand ils disent React) est-il protégé par XSS?

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?

63
user1210233

ReactJS est assez sûr par conception depuis

  1. Les variables de chaîne dans les vues sont automatiquement échappées
  2. Avec JSX, vous transmettez une fonction en tant que gestionnaire d'événements plutôt qu'une chaîne pouvant contenir du code malveillant.

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 ...

"Attention"

Il vous reste encore des vecteurs d’attaque XSS à manipuler dans React!

1. XSS via 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>

2. XSS via un attribut a.href

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>

3. XSS via des accessoires contrôlés par l'attaquant

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

67
Marty Aghajanyan

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


Modifier:

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!

49
John Ruddell