dangerouslySetInnerHTML 的安全替代品
Safe alternative to dangerouslySetInnerHTML
我想在我的网站上有一个动态博客(使用 React)。最初,我打算将 posts 存储在我的数据库中的原始 HTML 中,并使用 dangerouslySetInnerHTML 生成内容。但是,我担心安全隐患。虽然我的应用程序没有任何敏感数据,但我对 XSS 不够精通,无法了解打开我的应用程序可能面临的所有危险。
我很好奇是否有一种高效、安全的方法可以在我的应用程序中动态加载博客页面。在这种情况下使用 https://github.com/odysseyscience/react-router-proxy-loader 会有用吗?将 blog post JSX 文件夹与我的应用程序的其余部分分开,并使用它加载它(诚然,我不确定 react-router-proxy-loader 是如何工作的)。
我乐于接受建议。
如果 XSS 是您最关心的问题,您可以使用 DOMPurify
to sanitize your HTML before inserting it in the DOM via dangerouslySetInnerHTML
. It's just 10K minified. And it works in Node too.
https://facebook.github.io/react/tips/dangerously-set-inner-html.html
"The prop name dangerouslySetInnerHTML is intentionally chosen to be frightening. ..."
"After fully understanding the security ramifications and properly sanitizing the data..."
我想,如果你相信你自己的 CMS/Server(而不是从第 3 方接收),它已经清理了数据(这一步也完成了),那么你可以使用 dangerouslySetInnerHTML
.
正如 Morhaus 所说,也许使用 DOMPurify 因为它(奖金)可能会处理这个不幸的位:"so the HTML provided must be well-formed (ie., pass XML validation)." 我怀疑某些内容使用 [=27 的非 XML 版本=] 否则可能是一个问题。 (注意:我自己还没有用过,因为我和你一样是新手。)
如果您 确定 输入 HTML 是安全的(没有 XSS 风险)但可能格式不正确(例如文本中有一个随机的 <
),并且您想防止您的应用程序因意外的 DOM 更改而失败,那么您可以试试这个:
function sanitize(html) {
var doc = document.createElement('div');
doc.innerHTML = html;
return doc.innerHTML;
}
(基于)
但如果您对您的 HTML 可能是 not-XSS-safe 有丝毫怀疑,请使用上述 DOM 净化。
我遇到了同样的问题,但最终得到了更好的解决方案。如果您输入类似下面的内容,并且解决方案将适用于您使用 lodash
<em>paragraph text example:</em>
我的解决方案:
import _ from 'lodash';
const createMarkup = encodedHtml => ({
__html: _.unescape(encodedHtml),
});
/* eslint-disable react/no-danger */
const Notes = ({ label }) => (
<div>
<div dangerouslySetInnerHTML={createMarkup(label)} />
</div>
);
文章 How to prevent XSS attacks when using dangerouslySetInnerHTML in React 建议使用 jam3/no-sanitizer-with-danger eslint 规则来检查传递给 dangerouslySetInnerHTML 的内容是否包含在此清理函数中
有效代码示例为
const sanitizer = dompurify.sanitize;
return <div dangerouslySetInnerHTML={{__html: sanitizer(title)}} />; // Good
它还描述了 3 个消毒剂库:
DOMPurify
Xss.
xss-filters。
如其他答案所述,许多库(dompurify, xss 等)可以解析您提供给浏览器的 HTML,删除任何恶意部分并安全地显示它。
问题是:如何强制使用这些库。
为此,您可以安装 RisXSS,这是一个 ESLint 插件,它会警告 dangerouslySetInnerHTML
如果 您之前没有对其进行清理(从某种意义上说,这是 react/no-danger
ESLint 规则的改进版本)。
为此,安装 dompurify
和 eslint-plugin-risxss
:
npm install dompurify eslint-plugin-risxss
将 risxss
添加到您的 ESLint 插件,然后使用 DOMPurify:
import { sanitize } from 'dompurify';
export const MyArticle = ({ post }) => (
<>
<div dangerouslySetInnerHTML={{ post.content }} /> {/* You will receive a warning */}
<div dangerouslySetInnerHTML={{ __html: sanitize(post.content) }} /> {/* All good here */}
</>
);
免责声明:我是 RisXSS 插件的贡献者。
使用 React 库 Interweave.
- 安全地渲染 HTML 而不使用 dangerouslySetInnerHTML。
- 安全剥离 HTML 个标签。
- 自动 XSS 和注入保护。
- 使用过滤器清除 HTML 属性。
- 使用匹配器插入组件。
- 自动链接 URL、IP、电子邮件和主题标签。
- 渲染 Emoji 和图释字符。
Safe alternative to dangerouslySetInnerHTML
I'm curious if there's a performant, safe way to dynamically load blog pages within my app
有趣的是,虽然问题是 dangerouselySetInnerHTML
的替代方法,但所有答案都指示无论如何都要使用它。这是否意味着您别无选择?不,只是不容易。
备选方案 1:改写您的应用以将数据传递给组件
Initially, I was going to store the posts in raw HTML
从回答来看似乎没有这样的要求。它可以作为一个简单的解决方案来实现,不用担心与您的组件匹配的数据模式。但这不太可能是硬性要求。
您的应用程序 re-architect 应该可以不依赖于存储原始数据 HTML,尽管这可能意味着很多工作,具体取决于应用程序。
备选方案 2:不要编写自己的页面构建器
如果您只是想在自己的网站上创建一个博客,那么编写自己的页面构建器可能不值得。即使您想与网站的其他部分紧密集成,如果您使用 WordPress 之类的东西,那仍然是可能的。
备选方案 3(仅限 WordPress):使用 InnerBlocks
如果您当前在 WordPress 区块中使用 dangerouselySetInnerHTML
,您可以将其转换为使用 InnerBlocks
。
我想在我的网站上有一个动态博客(使用 React)。最初,我打算将 posts 存储在我的数据库中的原始 HTML 中,并使用 dangerouslySetInnerHTML 生成内容。但是,我担心安全隐患。虽然我的应用程序没有任何敏感数据,但我对 XSS 不够精通,无法了解打开我的应用程序可能面临的所有危险。
我很好奇是否有一种高效、安全的方法可以在我的应用程序中动态加载博客页面。在这种情况下使用 https://github.com/odysseyscience/react-router-proxy-loader 会有用吗?将 blog post JSX 文件夹与我的应用程序的其余部分分开,并使用它加载它(诚然,我不确定 react-router-proxy-loader 是如何工作的)。
我乐于接受建议。
如果 XSS 是您最关心的问题,您可以使用 DOMPurify
to sanitize your HTML before inserting it in the DOM via dangerouslySetInnerHTML
. It's just 10K minified. And it works in Node too.
https://facebook.github.io/react/tips/dangerously-set-inner-html.html
"The prop name dangerouslySetInnerHTML is intentionally chosen to be frightening. ..."
"After fully understanding the security ramifications and properly sanitizing the data..."
我想,如果你相信你自己的 CMS/Server(而不是从第 3 方接收),它已经清理了数据(这一步也完成了),那么你可以使用 dangerouslySetInnerHTML
.
正如 Morhaus 所说,也许使用 DOMPurify 因为它(奖金)可能会处理这个不幸的位:"so the HTML provided must be well-formed (ie., pass XML validation)." 我怀疑某些内容使用 [=27 的非 XML 版本=] 否则可能是一个问题。 (注意:我自己还没有用过,因为我和你一样是新手。)
如果您 确定 输入 HTML 是安全的(没有 XSS 风险)但可能格式不正确(例如文本中有一个随机的 <
),并且您想防止您的应用程序因意外的 DOM 更改而失败,那么您可以试试这个:
function sanitize(html) {
var doc = document.createElement('div');
doc.innerHTML = html;
return doc.innerHTML;
}
(基于)
但如果您对您的 HTML 可能是 not-XSS-safe 有丝毫怀疑,请使用上述 DOM 净化。
我遇到了同样的问题,但最终得到了更好的解决方案。如果您输入类似下面的内容,并且解决方案将适用于您使用 lodash
<em>paragraph text example:</em>
我的解决方案:
import _ from 'lodash';
const createMarkup = encodedHtml => ({
__html: _.unescape(encodedHtml),
});
/* eslint-disable react/no-danger */
const Notes = ({ label }) => (
<div>
<div dangerouslySetInnerHTML={createMarkup(label)} />
</div>
);
文章 How to prevent XSS attacks when using dangerouslySetInnerHTML in React 建议使用 jam3/no-sanitizer-with-danger eslint 规则来检查传递给 dangerouslySetInnerHTML 的内容是否包含在此清理函数中
有效代码示例为
const sanitizer = dompurify.sanitize;
return <div dangerouslySetInnerHTML={{__html: sanitizer(title)}} />; // Good
它还描述了 3 个消毒剂库:
DOMPurify
Xss.
xss-filters。
如其他答案所述,许多库(dompurify, xss 等)可以解析您提供给浏览器的 HTML,删除任何恶意部分并安全地显示它。
问题是:如何强制使用这些库。
为此,您可以安装 RisXSS,这是一个 ESLint 插件,它会警告 dangerouslySetInnerHTML
如果 您之前没有对其进行清理(从某种意义上说,这是 react/no-danger
ESLint 规则的改进版本)。
为此,安装 dompurify
和 eslint-plugin-risxss
:
npm install dompurify eslint-plugin-risxss
将 risxss
添加到您的 ESLint 插件,然后使用 DOMPurify:
import { sanitize } from 'dompurify';
export const MyArticle = ({ post }) => (
<>
<div dangerouslySetInnerHTML={{ post.content }} /> {/* You will receive a warning */}
<div dangerouslySetInnerHTML={{ __html: sanitize(post.content) }} /> {/* All good here */}
</>
);
免责声明:我是 RisXSS 插件的贡献者。
使用 React 库 Interweave.
- 安全地渲染 HTML 而不使用 dangerouslySetInnerHTML。
- 安全剥离 HTML 个标签。
- 自动 XSS 和注入保护。
- 使用过滤器清除 HTML 属性。
- 使用匹配器插入组件。
- 自动链接 URL、IP、电子邮件和主题标签。
- 渲染 Emoji 和图释字符。
Safe alternative to dangerouslySetInnerHTML
I'm curious if there's a performant, safe way to dynamically load blog pages within my app
有趣的是,虽然问题是 dangerouselySetInnerHTML
的替代方法,但所有答案都指示无论如何都要使用它。这是否意味着您别无选择?不,只是不容易。
备选方案 1:改写您的应用以将数据传递给组件
Initially, I was going to store the posts in raw HTML
从回答来看似乎没有这样的要求。它可以作为一个简单的解决方案来实现,不用担心与您的组件匹配的数据模式。但这不太可能是硬性要求。
您的应用程序 re-architect 应该可以不依赖于存储原始数据 HTML,尽管这可能意味着很多工作,具体取决于应用程序。
备选方案 2:不要编写自己的页面构建器
如果您只是想在自己的网站上创建一个博客,那么编写自己的页面构建器可能不值得。即使您想与网站的其他部分紧密集成,如果您使用 WordPress 之类的东西,那仍然是可能的。
备选方案 3(仅限 WordPress):使用 InnerBlocks
如果您当前在 WordPress 区块中使用 dangerouselySetInnerHTML
,您可以将其转换为使用 InnerBlocks
。