我认为使用 React 的 dangerouslySetInnerHTML
属性将从服务器获取的标记放置在页面上是很常见的,即
const SomeComponent = () => {
const [markup, setMarkup] = useState(null)
useEffect(() => {
const resp = await fetch(...)
setMarkup(resp.content)
})
return <div dangerouslySetInnerHTML={{ __hmtl: markup }} />
}
如果这是一个不同的场景,并且标记来自页面上的表单,那么这显然会带来风险,因为您不能信任表单上输入的数据,而且我们不会在此处进行任何清理。
但是,我们将从服务器返回的数据放在页面上,因此大概存在一定程度的信任。对服务器的调用发生在代码中,并且我们大概知道我们正在调用的 API。
但是,即使我们信任服务器,考虑来自受信任服务器的数据实际上是不明智的吗?不良行为者可以在数据返回之前干预线路吗?
最佳答案
完全信任的问题 dangerouslySetInnerHTML
有很多原因需要对dangerouslySetInnerHTML
采取最低限度的预防措施。 。由于浏览器的逻辑是在其他地方定义的,因此其他地方就会成为故障点。
- 审查和修改 HTML 代码逻辑构建方式的内部流程是否失败了?这是否允许 XSS 攻击?
- 是否有人忘记续订 SSL 证书?域名注册?有人已经抢注了它,现在您的应用程序使用来自被劫持域的 API?
- DNS 域名服务器是否遭到黑客攻击,导致您的 API 域指向其他服务器?路由器或任何中间网络设备怎么样?
- 您自己的服务器被黑客入侵了吗?可能性最小(眨眼),但也有可能。
安全使用dangerouslySetInnerHTML
但是,有时您需要dangerouslySetInnerHTML
,因为这是最简单的解决方案。例如,通过将其保存并存储为原始 HTML,可以非常轻松地存储、保留和检索粗体、斜体等标记。
至少,请清理任何 <script>
的数据在将其发送给用户之前进行标记,以绝对消除任何有害的可能性。您可以通过使用 document.createElement()
转换 HTML 来完成此操作,然后删除任何 <script>
标记节点。
有趣的事实:当您使用 <script>
创建元素时,SO 的演示不喜欢它。标签!下面的代码片段不会运行,但它确实可以在: Full Working Demo at JSBin.com 处运行。 .
var el = document.createElement( 'html' );
el.innerHTML = "<p>Valid paragraph.</p><p>Another valid paragraph.</p><script>Dangerous scripting!!!</script><p>Last final paragraph.</p>";
var scripts = el.getElementsByTagName( 'script' );
for(var i = 0; i < scripts.length; i++) {
var script = scripts[i];
script.remove();
}
console.log(el.innerHTML);
document.getElementById('main').append(el);
关于reactjs - 使用angerouslySetInnerHTML 向页面呈现服务器响应而不进行清理是否明智?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64811926/