react logo examples ejemplos documentacion reactjs security xss

reactjs - logo - ¿Qué significa cuando dicen que React está protegido por XSS?



react logo (2)

Leí esto en el tutorial de React. ¿Qué significa esto?

Reaccionar es seguro. No estamos generando cadenas HTML, por lo que la protección XSS es la predeterminada.

¿Cómo funcionan los ataques XSS si React es seguro? ¿Cómo se logra esta seguridad?


React escapa automáticamente de las variables por usted ... Evita la inyección de XSS a través de cadenas HTML con Javascript malicioso. Naturalmente, las entradas se desinfectan junto con esto.

Por ejemplo, digamos que tienes esta cadena

var htmlString = ''<img src="javascript:alert(''XSS!'')" />'';

si intentas hacer que esta cadena reaccione

render() { return ( <div>{htmlString}</div> ); }

literalmente verá en la página la cadena completa, incluida la etiqueta del elemento <span> . aka en el navegador verá <img src="javascript:alert(''XSS!'')" />

si ves la fuente html verías

<span>"<img src="javascript:alert(''XSS!'')" />"</span>

Aquí hay más detalles sobre lo que es un ataque XSS

Básicamente, React lo hace para que no pueda insertar marcado a menos que cree los elementos usted mismo en la función de representación ... dicho esto, tienen una función que permite tal representación se llama dangerouslySetInnerHTML ... aquí hay más detalles al respecto

Editar:

Pocas cosas a tener en cuenta, hay formas de evitar lo que React escapa. Una forma más común es cuando los usuarios definen accesorios para su componente. ¡No extienda ningún dato de la entrada del usuario como accesorios!


ReactJS es bastante seguro por diseño ya que

  1. Las variables de cadena en las vistas se escapan automáticamente
  2. Con JSX, pasa una función como controlador de eventos, en lugar de una cadena que puede contener código malicioso

así que un ataque típico como este no funcionará

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>

pero ...

❗❗❗Advertencia❗❗❗

¡Todavía hay algunos vectores de ataque XSS que debes manejar en React!

1. XSS a través de dangerouslySetInnerHTML

Cuando usa dangerouslySetInnerHTML , debe asegurarse de que el contenido no contenga javascript. Reaccionar no puede hacer nada aquí por ti.

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 a través del atributo a.href

Ejemplo 1: uso de javascript: código

Haga clic en "Ejecutar fragmento de código" -> "Mi sitio web" para ver el resultado

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>

Ejemplo 2: uso de datos codificados en base64:

Haga clic en "Ejecutar fragmento de código" -> "Mi sitio web" para ver el resultado

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 a través de accesorios controlados por el atacante

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>

Aquí hay más recursos.