NextPDF Laravel 패키지 보안 및 운영
한눈에 보기
섹션 제목: “한눈에 보기”이 패키지는 고정된 응답 헤더 집합을 적용하고, 다운로드 파일 이름을 정제하며, 워커에서 큐 출력 경로를 검증하고, 타임스탬프 기관으로 보내는 HTTP 요청을 요청 위조 인식 클라이언트로 감쌉니다. 이 페이지는 위협 모델과 각 제어에 필요한 배포 구성을 설명합니다.
composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-config개념 개요
섹션 제목: “개념 개요”이 패키지는 PDF 엔진을 웹 프레임워크에 맞게 조정합니다. 신뢰 경계는 HTTP 요청과 큐 전송입니다. 아래 제어는 응답 처리, 역직렬화된 작업 페이로드, 그리고 타임스탬프 기관으로 향하는 아웃바운드 HTTP를 다룹니다.
API 표면 — 위협 모델
섹션 제목: “API 표면 — 위협 모델”| 자산 | 위협 | 이 패키지의 제어 | 필요한 배포 구성 |
|---|---|---|---|
| PDF HTTP 응답 | 콘텐츠 유형 스니핑, 클릭재킹, 인덱싱 | 모든 PdfResponse 팩토리에 고정 헤더 집합을 설정 | 없음. 헤더는 구성할 수 없습니다 |
| 다운로드 파일 이름 | 헤더 주입, Content-Disposition 대상 경로 순회 | 파일 이름 정제기가 구분자, 제어 문자, 널 바이트를 제거 | 없음. 정제기는 항상 실행됩니다 |
| 큐 작업 출력 경로 | 변조된 직렬화 페이로드를 통한 임의 파일 쓰기 | 워커의 handle()에서 경로 검증 | 출력을 통제된 스토리지 경로로 라우팅 |
| 아웃바운드 TSA HTTP | 서버 측 요청 위조, 평문 변조 | 요청 위조 인식 HTTP 클라이언트. 명시적으로 완화하지 않는 한 HTTPS가 강제됨 | 다음을 유지: tsa.allow_insecure_http = false. SPKI 고정 |
| 공유 워커 상태 | 장기 실행 워커의 요청 간 상태 누출 | 잠긴 글꼴 레지스트리. 경계가 있는 이미지 캐시. 팩토리에 바인딩된 문서 | 다음을 설정: preload_fonts. 컨테이너 메모리 제한 설정 |
응답 강화
섹션 제목: “응답 강화”모든 PdfResponse 팩토리는 고정된 헤더 집합을 설정합니다.
Cache-Control: private, max-age=0, must-revalidatePragma: publicX-Content-Type-Options: nosniffX-Frame-Options: DENYContent-Security-Policy: default-src 'none'X-Robots-Tag: noindex, nofollowReferrer-Policy: no-referrer
이 값들은 PdfResponse의 상수이며 구성할 수 없습니다. 이 패키지의 테스트 스위트는 스트리밍 변형을 포함해 모든 팩토리 메서드에서 각 헤더를 검증합니다.
다운로드 파일 이름은 Content-Disposition 헤더에 도달하기 전에 정제기를 거칩니다. 정제기는 경로 구분자, 제어 문자, 널 바이트를 제거하고, ASCII가 아닌 이름에는 RFC 5987 filename*= 매개변수를 생성합니다. 빈 파일 이름은 document.pdf가 됩니다.
큐 페이로드 검증
섹션 제목: “큐 페이로드 검증”GeneratePdfJob는 큐 전송을 위해 클로저를 직렬화합니다. 출력 경로는 디스패치 시점이 아니라 워커의 handle() 내부에서 검증됩니다. 이 검증은 다음을 거부합니다.
- 경로의 널 바이트,
- 스트림 래퍼 스킴(예:
php://), ..경로 순회 세그먼트,- 확장자가
.pdf로 끝나지 않는 모든 경로(대소문자 구분 없음).
각 거부는 InvalidArgumentException을 발생시킵니다. 검증은 소비 시점에 실행됩니다. Redis 또는 데이터베이스 전송의 직렬화된 페이로드는 워커가 읽기 전에 변조될 수 있습니다. 출력 경로를 통제된 스토리지 디렉터리로 라우팅하십시오. 검증되지 않은 요청 입력으로부터 경로를 파생하지 마십시오.
타임스탬프 기관으로의 아웃바운드 HTTP
섹션 제목: “타임스탬프 기관으로의 아웃바운드 HTTP”타임스탬프 기관이 구성되면 이 패키지는 PSR-18 Psr\Http\Client\ClientInterface를 바인딩합니다. PSR-18 클라이언트는 PSR-7 요청을 보내고 PSR-7 응답을 반환합니다(PSR-18 §2). 바인딩된 클라이언트는 curl 기반 클라이언트를 요청 위조를 인식하는 계층으로 감싸며, tsa.allow_insecure_http가 명시적으로 true가 아닌 한 HTTPS를 강제합니다.
타임스탬프 기관은 Premium 등급 기능입니다. 여기에 문서화된 Core 패키지는 HTTP 클라이언트와 타임스탬프 클라이언트 연결을 바인딩합니다. 서명 자체에는 nextpdf/premium이 필요합니다. 이 페이지는 B-B를 넘어서는 PAdES 베이스라인 동작을 문서화하지 않습니다. 더 높은 베이스라인은 범위를 벗어납니다.
타임스탬프 기관에 대한 운영 지침:
- 프로덕션에서는
tsa.allow_insecure_http를false로 유지하십시오. - 구성 키
tsa.pinned_public_keys를 타임스탬프 기관 인증서의 base64 SHA-256 SPKI 해시(RFC 7469 형식)로 설정하십시오. - 고정된 인증서가 만료되기 전에 변경된 SPKI가 기록되도록
tsa.warn_on_key_rotation를true로 유지하십시오. - 구성 키
tsa.url은 신뢰할 수 있는 구성에서만 가져오십시오. 운영자가 관리 화면에서 이를 설정할 수 있다면 요청 위조 노출을 줄이기 위해 이그레스 방화벽 또는 DNS 정책을 적용하십시오.
진단에는 Psr\Log\LoggerInterface를 사용하십시오. 보간된 문자열이 아니라 구조화된 컨텍스트를 전달하십시오. PSR-3은 플레이스홀더 이스케이핑을 로거 구현에 맡기며, 호출자가 컨텍스트 값을 미리 이스케이프하지 않도록 지시합니다(PSR-3 §1.2). 로그에 남는 내부 세부 정보를 줄이려면 메시지나 트레이스가 아니라 예외 클래스를 기록하십시오.
코드 샘플 — 프로덕션
섹션 제목: “코드 샘플 — 프로덕션”<?php
declare(strict_types=1);
// .env — production timestamp-authority hardening// NEXTPDF_TSA_URL=https://tsa.example.test// NEXTPDF_TSA_ALLOW_INSECURE_HTTP=false// NEXTPDF_TSA_WARN_ROTATION=true
return [ 'tsa' => [ 'url' => env('NEXTPDF_TSA_URL'), 'allow_insecure_http' => env('NEXTPDF_TSA_ALLOW_INSECURE_HTTP', false), 'warn_on_key_rotation' => env('NEXTPDF_TSA_WARN_ROTATION', true), 'pinned_public_keys' => [ // base64 SHA-256 SPKI hashes of the TSA certificate ], ],];예외 사례 및 주의 사항
섹션 제목: “예외 사례 및 주의 사항”- 응답 헤더 집합은 고정되어 있습니다. 다른 CSP가 필요한 애플리케이션은 팩토리가 응답을 반환한 후에 응답을 후처리해야 합니다.
- 경로 검증은 워커에서 실행됩니다. 잘못된 경로는
dispatch()를 통과하고 작업이 실행될 때만 실패합니다. tsa.allow_insecure_http = true는 HTTPS 강제를 제거하고 타임스탬프 신뢰를 약화시킵니다. 이를 로컬 개발에만 제한하십시오.- 글꼴 레지스트리는 워밍업 후에 잠깁니다. 장기 실행 워커에서 런타임에 글꼴을 등록하려는 시도는 설계상 거부됩니다.
보안 제어는 상수 시간의 문자열 및 배열 연산이며 요청당 측정 가능한 비용을 추가하지 않습니다. 주요 운영 비용은 처음 사용할 때의 글꼴 구문 분석입니다. 첫 요청 지연을 피하려면 워커 부팅 시 글꼴을 사전 로드하십시오.
보안 참고 사항
섹션 제목: “보안 참고 사항”이 페이지는 패키지의 위협 모델 참조입니다. 여기에 설명된 제어는 소스에서 강제되고 테스트 스위트가 검증합니다. 운영자가 제공해야 하는 배포 구성은 위협 모델 표와 타임스탬프 기관 단계에 명시되어 있습니다.
적합성
섹션 제목: “적합성”| 주장 | 출처 | 조항 | 참조 ID |
|---|---|---|---|
| PSR-18 클라이언트가 PSR-7 요청을 보내고 PSR-7 응답을 반환함 | PSR-18 HTTP Client 표준 | §2 | |
| 호출자가 이스케이프하지 않은 구조화된 로그 컨텍스트를 전달함 | PSR-3 Logger 표준 | §1.2 |
RFC 7469 SPKI 고정은 tsa.pinned_public_keys 구성 키가 사용하는 형식을 가리키는 명칭입니다. 이 패키지는 운영자가 제공한 고정 값을 사용하며 RFC 자체를 구현하지 않습니다.
상업적 컨텍스트
섹션 제목: “상업적 컨텍스트”PAdES B-B 서명 및 타임스탬프 기관 통합에는 nextpdf/premium 패키지가 필요합니다. 이는 선택적 Enterprise 기능입니다. 여기에 문서화된 Core 패키지는 이를 채택하는 데 코드 변경이 필요하지 않습니다. 참조: https://nextpdf.dev/get-license/?intent=laravel-signing.
관련 항목
섹션 제목: “관련 항목”- /integrations/laravel/configuration/ — 모든 TSA, 서명, 큐 키
- /integrations/laravel/production-usage/ — DI 및 오류 처리 패턴
- /integrations/laravel/troubleshooting/ — 경로 검사가 입력을 거부하는 이유
- /integrations/laravel/boot-and-discovery/ — 장기 실행 워커의 바인딩 수명