Skip to content

安全防护

HTML 库内置多层安全防护,所有配置集中在 Config 的安全字段中。本页汇总安全相关的 API;安全特性的概念介绍详见 安全概述

安全配置字段

字段类型默认值安全作用
EnableSanitizationbooltrue内容消毒:移除危险标签、事件属性和恶意协议
MaxInputSizeint52428800 (50MB)输入大小限制,防止内存耗尽
MaxDepthint500DOM 嵌套深度限制,防止递归炸弹
ProcessingTimeouttime.Duration30s单文档处理超时,防止无限处理
AllowedBaseDirstring""文件操作目录沙箱,防止路径遍历
AuditAuditConfigDefaultAuditConfig()安全审计配置(详见 审计系统

禁用消毒的风险

EnableSanitization 默认启用,仅对完全可信的输入才可禁用。禁用后 HTML 原样解析,可能导致 XSS 风险。

内容消毒

启用时(默认),自动执行以下清洗:

防护层行为
危险标签移除 <script><style><iframe><object><embed>
事件属性移除所有 on* 属性(onclickonerror 等)
危险协议阻止 javascript:vbscript:
Data URL仅允许 data:image/*data:font/*data:application/pdf

被阻止的内容通过审计系统记录(需启用审计)。

路径安全

AllowedBaseDir 沙箱

限制文件操作(ExtractFromFile 等)到指定目录及其子目录:

go
cfg := html.DefaultConfig()
cfg.AllowedBaseDir = "/var/www/html"

p, err := html.New(cfg)
if err != nil {
    log.Fatal(err)
}
defer p.Close()

// ✅ 允许:目录内文件
result, err := p.ExtractFromFile("/var/www/html/page.html")

// ❌ 拒绝:目录外文件
_, err = p.ExtractFromFile("/etc/passwd")

设置后,文件路径必须在 AllowedBaseDir 内部才能被读取。跨平台支持:

  • Unix:解析符号链接(symlink),防止通过链接逃逸
  • Windows:解析 junction 和符号链接

留空(默认)表示不限制——适用于可信输入场景。

路径遍历检测

自动检测和阻止路径遍历尝试(如 ../../../etc/passwd),返回包装为 *FileError 的错误:

go
_, err := html.ExtractFromFile("../../../etc/passwd")
// err 包含 "path traversal detected" 信息

FileError.SafePath

文件错误自动脱敏路径信息,防止文件系统结构泄露:

go
type FileError struct {
    Op      string
    Path    string
    FileErr error
}

func (e *FileError) Error() string        // 输出已截断路径(仅文件名)
func (e *FileError) SafePath() string     // 仅返回文件名
func (e *FileError) MarshalJSON() ([]byte, error) // JSON 序列化时自动脱敏
go
_, err := html.ExtractFromFile("/var/www/secret/config.html")
if err != nil {
    var fileErr *html.FileError
    if errors.As(err, &fileErr) {
        fmt.Println(fileErr.SafePath()) // 输出:config.html(不含路径)
    }
}

TIP

FileError.Error()SafePath() 都返回截断后的安全路径(仅文件名),防止路径泄露。内部调试需要完整路径时可直接访问 Path 字段。

安全预设

HighSecurityConfig

面向高安全环境的预设配置,收紧所有限制并启用完整审计:

go
func HighSecurityConfig() Config

相比 DefaultConfig() 的安全字段覆盖:

字段默认值高安全值
MaxInputSize52428800 (50MB)10485760 (10MB)
MaxDepth500100
ProcessingTimeout30s10s
WorkerPoolSize42
AuditDefaultAuditConfig()HighSecurityAuditConfig()
go
cfg := html.HighSecurityConfig()
p, err := html.New(cfg)
if err != nil {
    log.Fatal(err)
}
defer p.Close()

安全相关错误

错误触发条件
ErrInputTooLarge输入超过 MaxInputSize
ErrMaxDepthExceededDOM 深度超过 MaxDepth
ErrProcessingTimeout处理超过 ProcessingTimeout
ErrInvalidFilePath文件路径校验失败(含路径遍历)
ErrInternalPanic内部 panic 被恢复

INFO

完整的错误类型定义(InputErrorConfigErrorFileError)和 errors.Is/errors.As 用法详见 常量与错误

恐慌恢复

所有提取操作内置 panic 恢复机制。即使处理过程中发生未预期的 panic,也会返回 ErrInternalPanic 而非让服务崩溃:

go
result, err := html.Extract(maliciousData)
if err != nil {
    if errors.Is(err, html.ErrInternalPanic) {
        // 输入可能触发了内部 bug
        log.Printf("panic recovered: %v", err)
    }
}

相关文档