Skip to content

보안 개요

TCPDF-Next는 보안 우선 설계 철학 위에 구축되었습니다. 암호화 기본 요소부터 HTML 파싱까지 모든 구성 요소는 취약점을 발견한 후 패치하는 대신 전체 범주의 취약점을 제거하도록 설계되었습니다.

보안 우선 설계 철학

TCPDF-Next의 보안은 레거시 코드베이스 위에 추가된 기능이 아닙니다. 첫날부터 모든 설계 결정에 영향을 미친 아키텍처적 제약입니다:

  • 기본적으로 거부 — 외부 리소스 로딩, 네트워크 요청, 파일 접근은 명시적으로 허용하지 않는 한 차단됩니다.
  • 실패 시 닫힘 — 보안 검사를 수행할 수 없는 경우(예: OCSP 응답자에 연결 불가), 안전하지 않게 진행하지 않고 작업이 실패합니다.
  • 심층 방어 — 여러 독립적인 보호 계층이 단일 우회로도 시스템이 손상되지 않도록 보장합니다.
  • 최소 공격 표면 — 런타임 Composer 종속성 없음. 모든 암호화 작업은 PHP의 내장 OpenSSL 및 Sodium 확장을 사용합니다.

AES-256 암호화 (레거시 알고리즘 없음)

TCPDF-Next는 PDF 2.0(ISO 32000-2, 리비전 6)에 정의된 AES-256 암호화만을 구현합니다. 모든 레거시 및 안전하지 않은 알고리즘은 영구적으로 거부됩니다:

알고리즘상태이유
AES-256-CBC지원됨PDF 2.0 표준, 알려진 실용적 공격 없음
RC4 (40비트 / 128비트)금지알려진 편향과 실용적 공격이 있는 스트림 암호
AES-128금지장기 기밀성을 위한 불충분한 여유
DES / 3DES미구현블록 크기 및 키 길이 취약점
MD5 (키 도출용)금지2004년 이후 충돌 공격
php
use YeeeFang\TcpdfNext\Encryption\EncryptionAlgorithm;
use YeeeFang\TcpdfNext\Encryption\Permissions;

$pdf->setEncryption()
    ->setAlgorithm(EncryptionAlgorithm::AES256)
    ->setUserPassword('reader-password')
    ->setOwnerPassword('admin-password')
    ->setPermissions(
        Permissions::PRINT_HIGH_QUALITY
        | Permissions::COPY
        | Permissions::ACCESSIBILITY
    )
    ->apply();

PAdES 디지털 서명 (B-B부터 B-LTA)

TCPDF-Next는 장기 유효성의 수준이 증가하는 전체 PAdES 기본 프로파일(ETSI EN 319 142-1)을 디지털 서명에 구현합니다:

수준설명검증 기간
PAdES B-B서명 인증서를 포함한 기본 CMS 서명인증서 유효기간 (~1-3년)
PAdES B-T+ 신뢰할 수 있는 TSA의 RFC 3161 타임스탬프TSA 인증서 유효기간 (~10-15년)
PAdES B-LT+ OCSP/CRL 데이터가 포함된 문서 보안 저장소알고리즘 보안 수명 (~15-30년)
PAdES B-LTA+ 무기한 재검증을 위한 아카이브 타임스탬프무기한 (주기적 재타임스탬프 시)

구현 세부 사항은 PAdES B-LTA 서명을 참조하세요.

DNS 핀닝을 통한 SSRF 보호

모든 외부 네트워크 요청(이미지 가져오기, TSA 통신, OCSP 조회)은 내장 SSRF 보호 기능이 있는 강화된 HTTP 클라이언트를 통과합니다:

  • DNS 핀닝 — 해석된 IP 주소는 연결 전에 검증됩니다. 사설 네트워크 범위(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), 루프백(127.0.0.0/8), 링크-로컬(169.254.0.0/16) 주소가 차단됩니다.
  • 프로토콜 제한 — 기본적으로 https://만 허용됩니다. 명시적으로 허용하지 않는 한 일반 http://는 거부됩니다.
  • 도메인 허용 목록 — 허용된 외부 도메인에 대한 구성 가능한 허용 목록.
  • 리디렉트 추적 — 구성 가능한 최대값(기본값: 3)으로 제한되며 각 홉에서 재검증.

경로 탐색 방지

모든 파일 경로 작업은 디렉토리 탐색 공격을 방지하기 위해 정리됩니다:

  • 임베디드 파일 이름에서 경로 구분자와 .. 시퀀스가 제거됩니다.
  • 폰트 파일 경로는 절대 정규 경로로 해석되고 허용된 디렉토리에 대해 검증됩니다.
  • HTML에서 참조되는 이미지 경로는 ResourcePolicy를 통해 명시적으로 구성된 디렉토리로 제한됩니다.

비밀번호 및 키에 대한 #[\SensitiveParameter]

비밀번호, 암호구문, 개인 키 또는 PIN을 받는 모든 메서드 파라미터에는 PHP 8.2의 #[\SensitiveParameter] 속성이 주석으로 달려 있습니다. 이는 민감한 값이 스택 트레이스, 오류 로그, 예외 메시지에서 자동으로 편집됨을 보장합니다:

php
public function setUserPassword(
    #[\SensitiveParameter] string $password
): self { /* ... */ }

public function setCertificate(
    string $certificate,
    #[\SensitiveParameter] string $privateKey,
    #[\SensitiveParameter] string $passphrase = ''
): self { /* ... */ }

중요 반환값에 대한 #[\NoDiscard]

보안에 중요한 결과(검증 결과, 서명 확인)를 반환하는 메서드에는 호출자가 반환값을 무시하는 것을 방지하기 위해 #[\NoDiscard]가 주석으로 달려 있습니다:

php
#[\NoDiscard]
public function validate(string $pdfPath): ValidationResult { /* ... */ }

#[\NoDiscard]
public function verify(): SignatureVerificationResult { /* ... */ }

이 반환값을 무시하면 컴파일러 경고가 생성되어, 개발 시 일반적인 보안 버그 범주를 포착합니다.

PHPStan 레벨 8 (에러 0개, 베이스라인 없음)

전체 코드베이스는 가장 엄격한 수준(레벨 8)에서 에러 0개, 베이스라인 파일 없이 PHPStan 정적 분석을 통과합니다. 이는 다음을 의미합니다:

  • 코드베이스 어디에도 @phpstan-ignore 주석이 없습니다.
  • 억제된 에러 카테고리가 없습니다.
  • 제네릭 및 템플릿 타입을 포함하여 모든 타입이 완전히 명시되어 있습니다.
  • 모든 데드 코드 경로가 제거되었습니다.

100% declare(strict_types=1)

TCPDF-Next의 모든 PHP 파일은 declare(strict_types=1)로 시작합니다. 예외는 없습니다. 이는 역사적으로 PHP 애플리케이션의 보안 취약점으로 이어진 전체 범주의 타입 강제 변환 버그를 제거합니다.

OWASP 규정 준수 고려사항

TCPDF-Next는 PDF 생성 라이브러리와 관련된 다음 OWASP 카테고리를 다룹니다:

OWASP 카테고리완화
A01 — 잘못된 접근 제어세분화된 PDF 권한, 인증서 기반 암호화
A02 — 암호화 실패AES-256만, 약한 알고리즘 없음, 상수 시간 비교
A03 — 인젝션HTML 정리, 경로 탐색 방지, eval() 없음
A05 — 보안 설정 오류안전한 기본값, 기본적으로 거부하는 리소스 정책
A06 — 취약한 구성요소런타임 종속성 없음, OpenSSL/Sodium을 통한 내장 암호화
A07 — 인증 실패#[\SensitiveParameter], sodium_memzero()를 통한 안전한 메모리 삭제
A10 — SSRFDNS 핀닝, 사설 네트워크 차단, 도메인 허용 목록

보안 문서

전체 보안 문서를 살펴보세요:

LGPL-3.0-or-later 라이선스로 배포됩니다.