Skip to content

セキュリティ保護 ​

HTML ライブラリは多層セキュリティ保護メカニズムを内蔵しています。すべての設定は Config のセキュリティフィールドに集約されています。このページはセキュリティ関連 API を扱います。セキュリティの概念紹介は セキュリティ概要 を参照してください。

セキュリティ設定フィールド ​

フィールド型デフォルトセキュリティの役割
EnableSanitizationbooltrueコンテンツサニタイズ:危険タグ、イベント属性、悪意のあるプロトコルを削除
MaxInputSizeint52428800 (50MB)入力サイズ制限、メモリ枯渇を防止
MaxDepthint500DOM ネスト深度制限、再帰爆弾を防止
ProcessingTimeouttime.Duration30sドキュメントごとの処理タイムアウト、無限処理を防止
AllowedBaseDirstring""ファイル操作ディレクトリサンドボックス、パストラバーサルを防止
AuditAuditConfigDefaultAuditConfig()セキュリティ監査設定(詳細は 監査システム)

警告

EnableSanitization はデフォルトで有効です。完全に信頼できる入力に対してのみ無効化してください。無効化すると HTML がそのまま解析され、XSS リスクが生じる可能性があります。

コンテンツサニタイズ ​

有効時(デフォルト)、以下のクリーンアップが自動実行されます:

保護レイヤー動作
危険タグ<script>、<style>、<iframe>、<object>、<embed> などを削除
イベント属性すべての on* 属性を削除(onclick、onerror など)
危険プロトコルjavascript:、vbscript: をブロック
Data URLdata: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: シンボリックリンクを解決、リンク経由の脱出を防止
  • 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内部パニックがリカバリされた

構造化エラー型 ​

上記のセンチネルエラーは、実際には 3 つの構造化エラー型でラップされて返され、原因特定に必要なコンテキストフィールドを運びます:

型フィールドメソッドUnwrap() の宛先
*InputErrorOp / Size / MaxSize / InputErrErrorInputErr(非 nil の場合)、それ以外は ErrInputTooLarge
*ConfigErrorField / Value / MessageErrorErrInvalidConfig
*FileErrorOp / Path / FileErrError / SafePath / MarshalJSONErrFileNotFound / 元のエラー / ErrInvalidFilePath

errors.Is(err, html.ErrXxx) でセンチネルのカテゴリを判定し、errors.As(err, &typedErr) で構造化コンテキスト(InputError.Size/MaxSize、ConfigError.Field など)を取り出す、という組み合わせで使用します。

INFO

3 つのエラー型の完全な定義と errors.Is/errors.As を使ったエラー処理パターンは 定数とエラー を参照してください。

パニックリカバリ ​

すべての抽出操作にパニックリカバリメカニズムが内蔵されています。処理中に予期しないパニックが発生しても、サービスをクラッシュさせず ErrInternalPanic を返します:

go
result, err := html.Extract(maliciousData)
if err != nil {
    if errors.Is(err, html.ErrInternalPanic) {
        // 入力が内部バグをトリガーした可能性
        log.Printf("panic recovered: %v", err)
    }
}

関連ドキュメント ​