他们说React受XSS保护是什么意思?


109

我在React教程上阅读了这一内容。这是什么意思?

React是安全的。我们不会生成HTML字符串,因此XSS保护是默认设置。

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

Answers:


178

从设计上来说,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"));
<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>

但是...

❗❗❗警告❗❗❗

在React中仍然需要处理一些XSS攻击媒介!

1.通过XSS 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"))
<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.通过a.href属性进行XSS

示例1:使用javascript:code

点击“运行代码段”->“我的网站”以查看结果

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>

示例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"));
<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

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>

这里有更多资源


13
这个答案太神奇了!最后是代码段和引用...!谢谢!
Ioanna

自从写了这个答案以来,React已经处理了上面的任何示例吗?我问,因为我读了以下幻灯片:slideshare.net/kseniadmitrieva/…幻灯片#20该用户控制的道具已在11月15日的React 0.14中修复”
omer

@omer否,react决定不关注React级别的攻击向量。这里有一些很好的意见,解释为什么他们没有在处理阵营水平github.com/facebook/react/issues/3473github.com/facebook/react/issues/3473#issuecomment-91349525github.com/facebook/react / issues / 3473#issuecomment-90594748
Cyber​​Panda Consulting

1
@omer您所指的问题是一个安全漏洞,并且已解决,但是我列出的第3点与该问题无关,您仍然可以通过在任何react版本下执行我的代码来检查第3点是否有效。
Cyber​​Panda Consulting

60

React自动为您转义变量...它可以防止通过带有恶意Javascript的字符串HTML进行XSS注入。自然,输入也将与此一起进行清理。

举例来说,假设您有这个字串

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

如果您尝试在响应中呈现此字符串

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

您会在页面上从字面上看到包括<span>元素标签在内的整个字符串。aka在浏览器中,您将看到<img src="javascript:alert('XSS!')" />

如果您查看源HTML,则会看到

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

这是有关什么是XSS攻击的更多详细信息

React基本上做到了这一点,因此除非您在render函数中自己创建元素,否则您将无法插入标记...也就是说,它们确实具有允许此类渲染其调用的功能dangerouslySetInnerHTML... 这里是有关它的更多详细信息


编辑:

没什么要注意的,有一些方法可以解决React逃脱的问题。一种更常见的方式是用户为组件定义道具。不要将用户输入的任何数据扩展为道具!


13
逃避一切?真?默认情况下,React是不安全的,您必须手动执行许多操作以及必须了解的攻击媒介。当您尝试使用{html}插入时,React所做的只是将html转义为字符串。但是还有一百万种允许XSS的其他方式,React不能阻止这种方式。<a href="{...}" />,<img src = {...} />,<iframe src =“ {...} />以及其他许多可注入可执行JavaScript的道具。然后通过style = {...}属性进行CSS脚本注入,@ Marty Aghajanyan在下面的回答实际上概述了可能的风险
andree

@andree感谢您指出我的错字。这是一个3岁的职位。显然,有一些方法可以解决React逃脱的问题,每个开发人员都应该对此感到厌倦。
约翰·鲁德尔

感谢您编辑您的答案@John Ruddell。没有冒犯,但是您的回答使React看起来比实际要安全得多,并且由于您的回答是该主题的第一个回答,我只想指出这一点。不幸的是,这是我在总体前端(不仅仅是React)安全性中看到的一个常见主题-表面上看起来很安全或很容易固定,但是当您深入研究时,结果却发现了很大的漏洞。基本的安全性问题应该具有容易找到的答案,这些答案在某处进行了汇总,但是不幸的是,这并不是我最近的经验。
Andree

好吧..随着时间的流逝,随着对安全性的测试,文档随之出炉。我们曾经有用的答案并不那么有用。困难的部分是,随着技术的不断变化,使所有答案都保持最新
John Ruddell 18-10-27
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.