我在React教程中读到了这个。这是什么意思?
React是安全的。我们不生成HTML字符串,因此XSS保护是默认设置。
如果React安全,XSS攻击如何工作?这种安全是如何实现的?
答案 0 :(得分:49)
React会自动为您转义变量...它会阻止通过带有恶意Javascript的字符串HTML进行XSS注入。当然,输入也会随之消毒。
例如,让我们说你有这个字符串
var htmlString = '<img src="javascript:alert('XSS!')" />';
如果您尝试在反应中呈现此字符串
render() {
return (
<div>{htmlString}</div>
);
}
您将在页面上直接看到包含<span>
元素标记的整个字符串。也就是在浏览器中,您将看到<img src="javascript:alert('XSS!')" />
如果您查看源html,您会看到
<span>"<img src="javascript:alert('XSS!')" />"</span>
Here is some more detail on what an XSS attack is
React基本上是这样做的,所以你不能插入标记,除非你自己在渲染函数中创建元素......据说他们确实有一个允许这样渲染它的函数dangerouslySetInnerHTML
。 。here is some more detail about it
很少有事情需要注意,有办法解决React逃脱的问题。一种更常见的方式是用户为组件定义道具。不要将用户输入的任何数据扩展为道具!
答案 1 :(得分:46)
ReactJS从设计上就很安全
所以这样的典型攻击将不会起作用
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>
但是...
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>
示例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>
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>
更多资源