You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML模板JavaScript注入重现与防护方案咨询(PDF转换场景)

重现HTML注入场景与防护方案

一、重现document.write注入影响PDF的场景

  • 在前端模板的动态填充区域插入如下注入代码:
    <script>document.write('failed');</script>
    
  • 用Postman将填充后的完整HTML字符串发送至后端ConvertHTMLStringToPDFStream接口
  • 后端SelectPdf引擎渲染时会执行这段脚本,document.write会直接改写HTML内容,最终生成的PDF里就会显示failed文本

二、为什么onerror脚本未生效?

SelectPdf的HTML转PDF引擎对JS的支持并非完全模拟浏览器环境:

  • onerror事件通常需要依赖浏览器的资源加载失败、DOM错误等场景触发,但SelectPdf的渲染流程是同步的,不会主动模拟这类触发条件
  • 部分异步或事件驱动的JS逻辑,在PDF的静态渲染流程中无法被执行

三、前端Angular防护方案

1. 严格的HTML内容清理

使用Angular内置DomSanitizer配合DOMPurify(直接集成库)过滤危险内容:

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import DOMPurify from 'dompurify';

constructor(private sanitizer: DomSanitizer) {}

sanitizeUserInput(input: string): SafeHtml {
  // 自动过滤script标签、on*属性等危险元素
  const cleanHtml = DOMPurify.sanitize(input);
  return this.sanitizer.bypassSecurityTrustHtml(cleanHtml);
}
  • 所有用户输入的动态内容,必须经过上述方法处理后,才能绑定到模板的[innerHTML]上

2. 模板层面限制

禁止在Angular模板中直接绑定未清理的原始HTML,必须使用经过 sanitize 处理后的SafeHtml对象

四、后端.NET(SelectPdf)防护方案

1. 直接禁用JavaScript执行

在转换方法中关闭JS支持,从根源阻止脚本运行:

public Stream ConvertHTMLStringToPDFStream(string htmlContent)
{
    using var converter = new HtmlToPdf();
    // 禁用所有JS执行,彻底避免脚本注入风险
    converter.Options.JavaScriptEnabled = false;
    
    using var doc = converter.ConvertHtmlString(htmlContent);
    var stream = new MemoryStream();
    doc.Save(stream);
    stream.Position = 0;
    return stream;
}

2. 预处理HTML过滤危险内容

使用HtmlAgilityPack清理HTML中的危险元素:

using HtmlAgilityPack;

private string SanitizeHtml(string htmlContent)
{
    var doc = new HtmlDocument();
    doc.LoadHtml(htmlContent);
    
    // 删除所有script标签
    foreach (var scriptNode in doc.DocumentNode.SelectNodes("//script") ?? Enumerable.Empty<HtmlNode>())
    {
        scriptNode.Remove();
    }
    
    // 移除所有on开头的事件属性
    foreach (var node in doc.DocumentNode.SelectNodes("//*[@*[starts-with(name(), 'on')]]") ?? Enumerable.Empty<HtmlNode>())
    {
        var unsafeAttrs = node.Attributes.Where(a => a.Name.StartsWith("on")).ToList();
        foreach (var attr in unsafeAttrs)
        {
            node.Attributes.Remove(attr);
        }
    }
    
    return doc.DocumentNode.OuterHtml;
}

转换PDF前先调用清理方法:

public Stream ConvertHTMLStringToPDFStream(string htmlContent)
{
    var cleanHtml = SanitizeHtml(htmlContent);
    using var converter = new HtmlToPdf();
    using var doc = converter.ConvertHtmlString(cleanHtml);
    
    var stream = new MemoryStream();
    doc.Save(stream);
    stream.Position = 0;
    return stream;
}

3. 限制资源加载权限

通过SelectPdf配置避免脚本触发远程请求:

converter.Options.WebPageLoadTimeout = 5; // 缩短加载超时,避免恶意资源阻塞
converter.Options.AllowRemoteContent = false; // 禁用远程资源加载
converter.Options.AllowLocalContent = true; // 仅允许本地资源(根据业务调整)

内容的提问来源于stack exchange,提问作者bob.mazzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:02:31