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
- Las variables de cadena en las vistas se escapan automáticamente
- 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.