React.js SharePoint现代WebPart中使用dangerouslySetInnerHTML渲染HTML的安全风险及替代方案咨询
首先直接给结论:是的,你当前的写法确实存在严重的安全风险,而且在SharePoint这种企业级环境里,风险会被放大,必须重视。
为什么会有风险?
dangerouslySetInnerHTML这个API的名字已经很直白了——它会完全信任你传入的HTML内容,直接把它渲染到DOM中,不会做任何过滤。如果用户(哪怕是误操作)在WebPart设置里输入了带有恶意代码的HTML,比如:
<script>alert('窃取你的SharePoint会话')</script> <img src=x onerror="fetch('/_api/web/currentuser', {credentials: 'include'}).then(res=>res.json()).then(data=>console.log(data))">
这些代码会直接在页面上执行,轻则篡改页面内容,重则窃取当前用户的SharePoint权限、操作站点数据,这就是典型的跨站脚本攻击(XSS)。
怎么消除风险?
核心思路是对用户输入的HTML进行安全净化,只保留合法的格式化标签(比如<p>、<b>、<ul>),过滤掉所有可能执行代码的标签和属性。最靠谱的方式是用成熟的净化库,比如dompurify,它专门用来处理这类场景,能覆盖几乎所有已知的XSS攻击向量。
具体实现步骤:
- 先在你的项目中安装依赖:
npm install dompurify --save npm install @types/dompurify --save-dev # 给TypeScript补全类型定义
- 在你的模态框组件(比如
MYModal2.tsx)中导入并使用它:
import DOMPurify from 'dompurify'; // ... 其他代码保持不变 <div className={contentStyles.body}> {/* 渲染前先净化HTML内容 */} <p dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(myprops.OurValue)}}> </p> </div>
这样处理后,所有恶意的脚本、事件处理器都会被自动过滤掉,只保留安全的富文本内容。
有没有更安全的替代方案?
如果可以调整用户输入的方式,用Markdown代替HTML会是更优的选择——Markdown语法简单,用户更容易上手,而且我们可以用react-markdown这类库把Markdown转换成安全的React元素,完全不需要用到dangerouslySetInnerHTML,从根源上避免风险。
实现步骤:
- 安装依赖:
npm install react-markdown --save
- 修改WebPart的属性面板,提示用户输入Markdown:
在MyModalPopupWebPart.ts的PropertyPane配置里,更新TextField的提示:
PropertyPaneTextField('OurValue', { label: "Our Value (支持Markdown格式,比如**加粗**、*斜体*)", multiline: true }),
- 在模态框组件中替换渲染方式:
import ReactMarkdown from 'react-markdown'; // ... 其他代码 <div className={contentStyles.body}> <ReactMarkdown>{myprops.OurValue}</ReactMarkdown> </div>
这样用户输入的Markdown会被转换成安全的React元素,完全不用担心XSS问题。
额外的防护建议
除了技术层面的处理,还要配合权限控制:确保只有可信的用户(比如站点管理员、内容编辑者)能修改这个WebPart的设置,从源头减少恶意输入的可能性。
内容的提问来源于stack exchange,提问作者John John

