当他们说React受XSS保护时意味着什么?

use*_*233 68 security xss reactjs

我在React教程上阅读了这篇文章.这是什么意思?

反应是安全的.我们不生成HTML字符串,因此XSS保护是默认设置.

如果React是安全的,XSS攻击如何工作?这种安全性如何实现?

Mar*_*yan 85

ReactJS设计非常安全

  1. 视图中的字符串变量会自动转义
  2. 使用JSX,您可以将函数作为事件处理程序传递,而不是可以包含恶意代码的字符串

所以像这样的典型攻击是行不通的

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"));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

但......

❗❗❗Warning❗❗❗

你还需要在React中处理一些XSS攻击向量!

1. XSS via dangerouslySetInnerHTML

当您使用时,dangerouslySetInnerHTML您需要确保内容不包含任何JavaScript.React不能为你做任何事情.

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"))
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

2. XSS通过a.href属性

示例1:使用javascript:代码

单击"运行代码段" - >"我的网站"以查看结果

const userWebsite = "javascript:alert('Hacked!');";

class UserProfilePage extends React.Component {
  render() {
    return (
      <a href={userWebsite}>My Website</a>
    )
  }
}

ReactDOM.render(<UserProfilePage />, document.querySelector("#app"));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

示例2:使用base64编码数据:

单击"运行代码段" - >"我的网站"以查看结果

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"));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

3. XSS通过攻击者控制的道具

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"));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

这里有更多的资源

  • 这个答案太神奇了!最后是代码段和引用...!谢谢! (5认同)

Joh*_*ell 51

React会自动为您转义变量...它会阻止通过带有恶意Javascript的字符串HTML进行XSS注入.当然,输入也会随之消毒.

例如,假设你有这个字符串

var htmlString = '<img src="javascript:alert('XSS!')" />';
Run Code Online (Sandbox Code Playgroud)

如果你尝试渲染这个字符串作出反应

render() {
    return (
        <div>{htmlString}</div>
    );
}
Run Code Online (Sandbox Code Playgroud)

你会在页面上看到整个字符串,包括<span>元素标记.也就是在浏览器中你会看到<img src="javascript:alert('XSS!')" />

如果您查看源html,您会看到

<span>"<img src="javascript:alert('XSS!')" />"</span>
Run Code Online (Sandbox Code Playgroud)

以下是有关XSS攻击的更多细节

React基本上是这样做的,所以你不能插入标记,除非你自己在渲染函数中创建元素...据说他们确实有一个允许这样渲染它的函数dangerouslySetInnerHTML... 这里有一些关于它的更多细节


编辑:

很少有事情需要注意,有办法解决React逃脱的问题.一种更常见的方式是用户为组件定义道具.不要将用户输入的任何数据扩展为道具!

  • 逃避一切?真?默认情况下,React并不安全,你必须手动完成许多事情并且必须要了解攻击向量.当您尝试使用{html}插入时,所有React都会将html转义为字符串.但是还有其他一百万种方法可以允许XSS,而React并不能防范它.<a href="{...}" />,<img rel="nofollow noreferrer" src = {...} />,<iframe src ="{...} /></iframe>以及大量允许注入可执行javascript的其他道具.然后通过style = {...} prop进行CSS脚本注入.@Marty Aghajanyan的回答实际上概述了可能存在的风险. (6认同)
  • 嗯……随着时间的推移,随着安全性的测试,文档会出来。我们曾经有用的答案现在没有那么有用了。困难的部分是使所有答案与不断变化的技术保持同步 (2认同)