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: 심볼릭 링크(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내부 패닉 복구됨

INFO

완전한 오류 타입 정의(InputError, ConfigError, FileError)와 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)
    }
}

관련 문서