Skip to content

React + AI 应用开发

AI Markdown、代码块和工具结果如何安全渲染?

模型输出默认是不可信输入,渲染层要同时解决安全、可读性、流式中间态和长文档性能。

适合阶段:资深前端 / 安全面试核心能力:XSS · Sanitization · 渲染性能

面试官想考什么

  • AI 输出能否直接用 dangerouslySetInnerHTML 考察输入不可信意识。
  • 链接、图片和 HTML 怎么处理? 考察 sanitizer 策略。
  • 流式 Markdown 为什么会闪烁? 考察增量解析边界。
  • 工具结果和模型文本如何区分? 考察数据来源与信任层级。

一句话回答

text
AI 文本和工具结果都按不可信输入处理,优先使用安全 AST 渲染,严格配置 Markdown sanitizer、协议白名单和 CSP;流式阶段采用轻量增量展示,完成后再做完整解析和高亮,工具结果用独立组件和数据 schema 呈现。

面试回答详解

1. 信任边界

text
模型文本 / 用户输入 / 检索内容 / 工具结果
        -> 统一不可信
        -> 解析、校验、清洗
        -> React 组件树

模型可能复述恶意 prompt,RAG 文档可能含脚本片段,工具结果可能被第三方系统污染。来源不同不代表可以跳过清洗。

2. 渲染策略

  • Markdown 解析为 AST,再映射到受控 React 组件。
  • 禁止或清洗 raw HTML、javascript:、危险 data URL 和不必要的 iframe。
  • 外链使用允许协议、rel="noreferrer noopener",必要时统一走安全跳转页。
  • 代码高亮使用已知语言白名单,避免把代码执行当成预览。
  • 复制、下载、引用等动作使用原始文本或结构化字段,不从 DOM 反解析。

3. 流式中间态

未闭合的代码围栏和 Markdown 表格会导致整棵 AST 反复变化。生成中可以显示纯文本、已完成段落或安全的简化格式;完成后再异步解析全文。不要为了“看起来像 Markdown”而在每个 token 上执行完整高亮。

4. 工具结果

工具结果应该有明确 schema,例如 type: tabletype: search_resulttype: chart_data。只允许 schema 对应的组件渲染,不把工具返回的 HTML 当作可信 UI。对下载链接、图片、文件名和错误字段继续做校验。

5. 生产防护

配合 CSP、Trusted Types、依赖更新、恶意样本测试和安全日志。Sanitizer 是纵深防御,不代替服务端权限、文件扫描和 URL 代理。敏感消息不应进入第三方高亮或分析脚本。

可直接背诵的 30 秒回答

text
我把模型输出、检索内容和工具结果都视为不可信输入,不直接拼 HTML。Markdown 先解析为 AST,再用受控组件渲染,配置 HTML、协议、图片和 iframe 白名单,并配合 CSP。流式过程中用轻量文本或已完成片段,结束后再完整解析和高亮。工具结果必须按 schema 使用独立组件展示。

扩展知识

安全和可用性的平衡

过度清洗可能破坏合法内容,所以需要明确产品允许的 Markdown 子集,并为被过滤内容提供可解释的降级,而不是静默执行。

面试官追问链

追问一:React 会自动防 XSS,为什么还危险?

  • 考察点:是否理解边界。
  • 回答方向:普通 JSX 会转义,但 dangerouslySetInnerHTML、URL、第三方组件、富文本插件和服务端拼接仍可能引入风险。

追问二:代码高亮库放在客户端有什么问题?

  • 考察点:性能和安全。
  • 回答方向:语言包会增加 bundle,解析长代码可能阻塞主线程,应按需加载、限制长度,必要时放 Web Worker。

追问三:如何允许少量公式或自定义标签?

  • 考察点:白名单设计。
  • 回答方向:定义有限语法和 schema,逐字段验证;不要开放任意 HTML 或任意组件名。

推荐阅读

基于 MIT 协议开源