compat-legacy 보안 및 운영
한눈에 보기
섹션 제목: “한눈에 보기”이 어댑터는 NextPDF 엔진의 보안 모델을 상속하고, 레거시 TCPDF 6.2.13에 비해 몇 가지 의도적인 강화 사항을 더합니다. 이 페이지는 제공되는 기능과 제공되지 않는 기능을 과장 없이 정확히 명시합니다. 서명 섹션은 주의 깊게 읽어야 합니다. 그 범위는 의도적으로 좁게 설정되어 있습니다.
강화된 레거시 동작
섹션 제목: “강화된 레거시 동작”기존 TCPDF 6.2.13의 세 가지 동작은 안전을 위해 변경되었으며 안전하지 않은 형태로 되돌리도록 구성할 수 없습니다:
| 우려 사항 | 레거시 TCPDF 6.2.13 | 어댑터 |
|---|---|---|
| 오류 처리 | Error()가 die()를 호출하여 프로세스를 종료합니다 | Error()가 RuntimeException을 던집니다. 관찰할 수 있고 포착할 수 있으며, 프로세스를 조용히 종료하지 않습니다. |
| HTML 실행 | 우회 경로를 통해 마크업에서 PHP를 실행할 수 있었습니다 | K_TCPDF_CALLS_IN_HTML 상수가 false로 고정되어 있어 마크업이 PHP 실행을 트리거할 수 없습니다. |
| 직접 출력 | Output()가 활성 출력 버퍼로 내용을 출력합니다 | 출력은 안전한 대상 브리지를 통해 라우팅됩니다. 호출자가 제어하는 출력 버퍼를 오염시키지 않습니다. |
오류 처리 변경은 프로세스가 갑자기 종료되는 대신 호출자가 실패를 관찰할 수 있어야 한다는 원칙을 따릅니다. OWASP ASVS 5.0 §16.5.3은 애플리케이션이 실패 시에도 안정적이고 안전하게 동작하며 fail-open 상황을 방지해야 한다고 명시합니다. die 대신 throw로 변경한 것은 그 원칙을 적용한 것입니다. HTML 강화는 코드 실행 싱크를 제거합니다. 이전 동작에 의존하던 레거시 코드는 /integrations/tcpdf-compat/migration/ 과정에서 수정해야 할 결함으로 취급해야 합니다. 고정된 조항 다이제스트는 페이지 프런트매터 citations에 있습니다.
암호화
섹션 제목: “암호화”이 어댑터는 TCPDF의 SetProtection()을 노출합니다. 이 호출은 NextPDF 엔진의 표준 보안 핸들러에 위임합니다.
- 표준 핸들러는 AES-256을 사용합니다. 레거시
$mode매개변수는 시그니처 호환성을 위해 허용되지만 무시됩니다. 이 메서드로 더 약한 암호를 선택할 방법은 없습니다. 엄격 모드가 켜져 있으면 기본값이 아닌$mode는 예외를 발생시켜 마이그레이션 과정에서 이를 인지하도록 강제합니다(tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php에서 검증됨). - 소유자 비밀번호가 제공되지 않으면, 어댑터는 사용자 비밀번호를 재사용하는 대신 암호학적으로 강력한 무작위 소유자 비밀번호를 생성합니다. 이는 사용자 수준 접근 권한을 가진 사용자가 문서에 대한 소유자 수준 제어 권한을 얻지 못하게 합니다.
- 인증서 기반(공개 키) 암호화는
SetProtection()을 통해 수행되지 않으며, 해당$pubkeys매개변수는 무시됩니다. 어댑터가 노출하는 최신 공개 키 암호화 진입점(setPublicKeyEncryption())을 사용해야 합니다. 이 진입점은 엔진에 위임합니다.
암호화 동작은 ISO 32000-2 §7에 설명된 표준 보안 핸들러를 반영합니다. 해당 조항은 암호화 딕셔너리 항목과 엔진이 사용하는 AES-256 표준 핸들러를 정의합니다. 이 문서는 출력물이 “기본적으로 안전하다”거나 “변조 방지된다”고 주장하지 않습니다. 사용하는 암호와 소유자 비밀번호 동작을 명시하며, 이는 코드가 실제로 수행하는 내용입니다. 고정된 조항 다이제스트는 페이지 프런트매터 citations에 있습니다.
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->AddPage();$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Encrypted document');
// User password set; owner password auto-generated (strong, random).$pdf->SetProtection([], 'user-secret');
$pdf->Output(__DIR__ . '/encrypted.pdf', 'F');디지털 서명 — 범위 설명
섹션 제목: “디지털 서명 — 범위 설명”이 섹션은 문자 그대로 읽어야 합니다. 의도적으로 보수적으로 작성되었습니다.
- TCPDF 레거시
setSignature()및addEmptySignatureAppearance()메서드는 코어 엔진 어댑터에서 구현되지 않았습니다. 기본 모드에서는 아무 작업도 하지 않으며, 엄격 모드에서는TcpdfNotImplementedException을 던집니다. - 디지털 서명은 이 어댑터를 통한 코어 배포판의 기능이 아닙니다. 베이스라인 서명 지원은 상용 NextPDF 에디션으로 제한됩니다.
- 상용 에디션을 사용하는 경우, 어댑터는 엔진에 위임하는 최신 서명 진입점(
setSignatureV2())을 노출합니다. 기본 프로파일은 베이스라인(B-B) 프로파일입니다. - 이 문서는 어떤 에디션도 이 어댑터를 통해 타임스탬프, 장기 검증 또는 아카이브 서명 프로파일을 생성한다고 주장하지 않습니다. 구체적으로, B-T, B-LT 또는 B-LTA 동작을 주장하지 않습니다. PAdES 베이스라인 사양 §6.1은 네 가지 별개의 베이스라인 수준(B-B, B-T, B-LT 및 B-LTA)을 정의하며, 각각 고유한 요구 사항을 가집니다. B-B는 베이스라인 수준이며, 상위 수준(타임스탬프, 장기, 아카이브)은 별개의 더 까다로운 프로파일입니다. 이 호환성 계층 문서의 범위에는 B-B 베이스라인만 포함됩니다. 상위 수준은 명시적으로 범위를 벗어나며, 이 문서는 어떤 에디션에 대해서도 상위 수준을 주장하지 않습니다. 고정된 조항 다이제스트는 페이지 프런트매터
citations에 있습니다. - 어느 곳에서도 “인증됨”, “보장됨”, “법적으로 유효함” 또는 “eIDAS 적격” 서명에 대한 주장을 하지 않습니다. 서명 정확성, 신뢰 앵커 정책 및 법적 유효성은 이 호환성 계층이 아니라 서명 에디션과 호출자 PKI의 책임입니다.
마이그레이션에 서명이 필요하다면 이를 별도의 작업 흐름으로 취급해야 합니다. 상용 에디션에서 최신 서명 API를 채택하고, 생성된 서명을 독립적인 검증기로 검증해야 합니다. TCPDF setSignature() 호출에 의존해서는 안 됩니다. 여기서는 아무 작업도 수행하지 않습니다.
레거시 setTimeStamp() 메서드는 시그니처 호환성을 위해 허용되며 알림을 발생시킵니다. 이 어댑터를 통해 타임스탬프 서명을 생성하지는 않습니다.
PDF/A 및 적합성
섹션 제목: “PDF/A 및 적합성”생성자의 pdfa 플래그는 시그니처 호환성을 위해 허용됩니다. PDF/A 아카이브 적합성에는 상용 NextPDF 에디션이 필요합니다. 어댑터는 엔진에 위임하는 enablePdfA()를 노출하며, 필요한 에디션이 없으면 엔진은 조치할 수 있는 구성 오류를 반환합니다. 어댑터는 PDF/A를 주장하면서 비적합 파일을 조용히 생성하지 않습니다.
출력은 항상 PDF 2.0(ISO 32000-2)입니다. ISO 32000-2 §7.5.2는 적합한 작성기가 문서 버전을 2.0으로 식별하고 저장 시 이를 이전 버전으로 낮추지 않도록 규정합니다. 따라서 setPDFVersion()은 이전 버전으로 낮출 수 없습니다(/integrations/tcpdf-compat/method-coverage/ §4 참조). 고정된 조항 다이제스트는 페이지 프런트매터 citations에 있습니다.
운영 지침
섹션 제목: “운영 지침”- 프로세스 종료 없음.
Error()가die()대신 예외를 던지므로, 렌더링 진입점을try/catch로 감싸고 실패를 애플리케이션의 오류 계약에 매핑해야 합니다. 렌더링 실패가 요청을 종료한다고 가정해서는 안 됩니다. - 출력 버퍼 안전성.
Output()은S일 때 바이트를 반환하고,F일 때 파일을 쓰고,E일 때 base64 MIME 본문을 반환하며,I/D일 때는 엔진 출력 경로를 통해 라우팅됩니다. 응답을 직접 제어할 수 있도록 워커와 HTTP 핸들러에서는S또는F를 선호해야 합니다. /integrations/tcpdf-compat/production-usage/를 참조하십시오. - 엄격 모드는 프로덕션 설정이 아닙니다. CI/감사 작업에만 사용해야 합니다. 프로덕션 렌더링 경로에서 발생하는 예외는 조용히 저하된 매개변수보다 더 나쁩니다.
- 상수 위생. 첫 번째 어댑터를 생성하기 전에
PDF_*/K_*상수를 정의해야 합니다. 두 개의 강화된 플래그(K_TCPDF_CALLS_IN_HTML,K_TCPDF_THROW_EXCEPTION_ERROR)는 완화할 수 없으며, 시도해서도 안 됩니다. - 무작위 소유자 비밀번호. 결정적 소유자 비밀번호에 의존한다면 이를 명시적으로 설정해야 합니다. 그렇지 않으면 문서마다 강력한 무작위 비밀번호가 생성되며 복구할 수 없습니다.
위협 모델 참고 사항
섹션 제목: “위협 모델 참고 사항”- 이미지 메서드의 경우, 스트림 래퍼 경로는 파일 시스템을 읽기 전에 거부됩니다. 이미지 유형 감지(
TcpdfImages::getImageFileType)는 모든scheme://경로(phar://,php://및 기타 PHP 스트림 래퍼)를 래퍼로 취급하고,file_get_contents/getimagesize탐지를 건너뛰며 확장자 전용 추론으로 폴백합니다. 이는 PHP 7.4 백포트 대상에서 phar 메타데이터 역직렬화 벡터를 차단합니다. 래퍼 경로를 임베드하는 것 자체는 엔진에 의해 거부됩니다. - 어댑터는 그 밖에는 엔진이 수행하는 범위를 넘어 이미지 또는 출력 메서드에 전달된 파일 경로를 검증하거나 정제하지 않습니다. 호출자가 제공한 경로와 URL은 애플리케이션 경계에서 신뢰할 수 없는 것으로 취급해야 합니다.
- HTML 메서드에 전달된 HTML은 TCPDF HTML 파서가 아니라 엔진에 의해 렌더링됩니다. 레거시 PHP 실행 싱크는 차단되었지만, 호출자가 제공한 HTML은 여전히 신뢰할 수 없는 입력으로 취급해야 합니다.
- 암호화는 표준 핸들러에 따라 저장 상태의 문서 기밀성을 보호합니다. 이는 애플리케이션의 전송 보안이나 접근 제어를 대체하지 않습니다.
참고 자료
섹션 제목: “참고 자료”- /integrations/tcpdf-compat/method-coverage/ —
SetProtection(),setSignature()의 정확한 동작 - /integrations/tcpdf-compat/configuration/ — 강화되어 구성할 수 없는 두 가지 플래그
- /integrations/tcpdf-compat/production-usage/ — 워커, 버퍼, 실패 처리
docs/TCPDF_COVERAGE.md— 권위 있는 커버리지 매트릭스- 패키지
NOTICE— 독립 구현 선언문