我想在我的网站上使用动态博客(使用React)。最初,我打算将帖子存储在我的数据库中的原始HTML中,并使用dangerouslySetInnerHTML生成内容。然而,我担心安全问题。虽然我的应用程序没有任何敏感数据,但我不熟悉XSS,知道我打开我的应用程序所带来的所有危险。
我很好奇是否有一种在我的应用中动态加载博客页面的高效,安全的方法。在这种情况下使用https://github.com/odysseyscience/react-router-proxy-loader会有用吗?有一个博客文件夹JSX与我的应用程序的其余部分分开并使用它加载它(诚然,我不确定react-router-proxy-loader如何工作)。
我愿意接受建议。
谢谢,
凯文
答案 0 :(得分:33)
如果您主要关注XSS,可以使用DOMPurify
清理HTML,然后再通过dangerouslySetInnerHTML
将其插入DOM。它只有10K缩小了。 And it works in Node too.
答案 1 :(得分:7)
https://facebook.github.io/react/tips/dangerously-set-inner-html.html
“故意命名dangerouslySetInnerHTML被故意选为令人恐惧的......”
“在充分了解安全后果并正确清理数据之后......”
我认为,如果您信任自己的CMS /服务器(而不是从第三方接收),它已经清理了数据(此步骤也已完成),那么您可以使用dangerouslySetInnerHTML
进行插入。
正如Morhaus所说,也许使用DOMPurify,因为它(奖励)可能处理这个不幸的一点:“所以提供的HTML必须是格式良好的(即,通过XML验证)。”我怀疑使用HTML5的非XML版本的某些内容可能会成为一个问题。 (注意:我还没有自己使用它,因为我很喜欢你。)
答案 2 :(得分:2)
如其他答案所述,许多库(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 插件的贡献者。
答案 3 :(得分:1)
如果您确定输入HTML是安全的(没有XSS风险)但可能格式不正确(例如,文本中有随机class YourCollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('categoriesConfigs', CollectionType::class, array(
'entry_type' => CategoriesConfigType::class,
'entry_options' => array('required' => false)
);
}
}
),并且您想要防止你的应用程序因为意外的DOM更改而失败,那么你可以试试这个:
<
(基于https://stackoverflow.com/a/14216406/115493)
但如果您对您的HTML可能不是XSS安全有任何疑问,请使用上面提到的DOMPurify。
答案 4 :(得分:1)
我遇到了同样的问题,并以更好的解决方案结束。如果您使用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>
);
答案 5 :(得分:0)
文章How to prevent XSS attacks when using dangerouslySetInnerHTML in React建议使用jam3 / no-sanitizer-with-danger eslint规则检查传递给危险SetInnerHTML的内容是否包装在此消毒剂函数中
有效代码示例为
const sanitizer = dompurify.sanitize;
return <div dangerouslySetInnerHTML={{__html: sanitizer(title)}} />; // Good
它还描述了3个消毒剂库:
DOMPurify
Xss。
xss-filters。