콘텐츠로 이동
getnextpdf.com

Enterprise 에디션

콘텐츠 무해화 및 재구성 — 심층 참조

이 페이지는 NextPDF\Enterprise\Security\Cdr 모듈의 심층 레퍼런스입니다. 이 모듈은 신뢰할 수 없는 PDF를 무해화하고 그 안전한 객체들로부터 깨끗한 파일을 재구성합니다. 파이프라인은 파싱, 승인 제어, 위협 탐지, 필터링, 참조 스크러빙, 재구성입니다. 출력은 입력의 보안 투영이며, 결코 증거용 사본이 아닙니다. 워크플로 지침은 먼저 CDR 기능 페이지를 읽으십시오.

이 기능은 NextPDF Enterprise (nextpdf/enterprise)에 포함되어 제공되며 Enterprise 티어 라이선스 엔벨로프로 활성화됩니다. 해당 자격이 없는 배포에서는 이 기능의 클래스가 로드되지 않습니다. 에디션을 비교하고 라이선스를 받으십시오.

심볼매개변수기본 동작반환예외 또는 실패 조건비고
CdrEngine::__construct없음내부 detector와 rebuilder를 구성CdrEngine선언된 것 없음주입 가능한 협력자 없음
CdrEngine::sanitizestring $pdfData, ?CdrPolicy $policy = nullCdrPolicy::standard() 하에 전체 파이프라인을 실행CdrResult적대적 입력에도 예외를 던지지 않음; 파싱 및 승인 실패는 거부된 결과를 반환결과는 거부를 무해화와 구별하여 보고함
CdrPolicy::__construct선택적 명명 매개변수 7개, 펜스 참조빈 제거 집합; allowUriActions false; flattenIncrementalUpdates true; 한도는 객체 100000개, 디코딩 256 MiB, 페이지 10000개, 팽창률 1000.0CdrPolicy선언된 것 없음final readonly; 빈 removeThreatTypes 목록은 아무것도 탐지하지 않음
CdrPolicy::standard없음레거시 위협 집합; URI 액션 제거; 기본 한도self선언된 것 없음손실을 일으키는 7개의 Strip* 케이스를 제외함
CdrPolicy::paranoid없음더 엄격한 한도의 레거시 위협 집합: 객체 50000개, 128 MiB, 페이지 5000개, 팽창률 100.0self선언된 것 없음손실을 일으키는 7개의 Strip* 케이스를 제외함
CdrPolicy::permissive없음JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData만 제거; URI 액션은 보존self선언된 것 없음신뢰할 수 있는 소스용
CdrPolicy::allThreatTypes없음손실을 일으키는 Strip* 케이스를 포함해 모든 ThreatType 케이스를 반환list<ThreatType>선언된 것 없음명시적 최대 스트립 옵트인
CdrPolicy::legacyThreatTypes없음7개의 Strip* 케이스를 제외한 모든 케이스를 반환list<ThreatType>선언된 것 없음standard()paranoid()의 기본 제거 집합
CdrPolicy::shouldRemoveThreatType $typeremoveThreatTypes에 대한 멤버십 테스트bool선언된 것 없음allowUriActionstrue일 때 UriAction에 대해 false를 반환
ThreatDetector::detectPdfReader $reader, CdrPolicy $policy정책의 위협 유형에 대해 모든 객체와 트레일러 카탈로그를 스캔list<DetectedThreat>예외를 던지지 않음; 파싱 불가능한 객체는 UnparseableObject 위협이 됨카탈로그 스캔은 /Names/JavaScript 트리를 포함함
CdrRebuilder::rebuildPdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policy안전한 객체들을 단일 리비전 %PDF-2.0 파일로 직렬화string선언된 것 없음; 재읽기 또는 /Length 검증에 실패한 객체는 건너뜀$policy는 향후 직렬화 조정을 위해 예약됨
DetectedThreat::__constructThreatType $type, int $objectNumber, string $description, string $location = ''불변 발견 값 객체DetectedThreat선언된 것 없음네 개의 프로퍼티 모두 public readonly
ThreatType문자열 백드 열거형20개 케이스: 레거시 13개와 옵트인 Strip* 케이스 7개해당 없음해당 없음아래 케이스 목록 참조
final class CdrEngine
{
public function __construct()
public function sanitize(string $pdfData, ?CdrPolicy $policy = null): CdrResult
}
final readonly class CdrPolicy
{
public function __construct(
public array $removeThreatTypes = [],
public bool $allowUriActions = false,
public bool $flattenIncrementalUpdates = true,
public int $maxObjects = 100_000,
public int $maxDecodedStreamBytes = 268_435_456,
public int $maxPageCount = 10_000,
public float $maxInflationRatio = 1000.0,
)
public static function standard(): self
public static function paranoid(): self
public static function permissive(): self
public static function allThreatTypes(): array
public static function legacyThreatTypes(): array
public function shouldRemove(ThreatType $type): bool
}
final class ThreatDetector
{
public function detect(PdfReader $reader, CdrPolicy $policy): array
}
final class CdrRebuilder
{
public function rebuild(PdfReader $reader, array $safeObjNums, array $removedObjNums, CdrPolicy $policy): string
}
final readonly class DetectedThreat
{
public function __construct(
public ThreatType $type,
public int $objectNumber,
public string $description,
public string $location = '',
)
}
enum ThreatType: string

레거시 케이스 13개가 기본 제거 집합을 이룹니다. Strip* 케이스는 설계상 손실을 일으키며 기본 정책에는 결코 들어가지 않습니다.

케이스백킹 값탐지 표면
ThreatType::JavaScriptjavascript임의의 객체상 /JS 키, 또는 /S /JavaScript 액션
ThreatType::AdditionalActionsadditional-actions임의의 객체상 /AA 딕셔너리
ThreatType::OpenActionopen-action임의의 객체상 /OpenAction
ThreatType::LaunchActionlaunch-action/S /Launch 액션
ThreatType::RemoteGoToremote-goto/S /GoToR 또는 /S /GoToE 액션
ThreatType::SubmitFormsubmit-form/S /SubmitForm 액션
ThreatType::ImportDataimport-data/S /ImportData 액션
ThreatType::EmbeddedFilesembedded-files/EmbeddedFiles 이름 트리 또는 /EF 딕셔너리
ThreatType::RichMediarich-media/Subtype /RichMedia
ThreatType::NamedJavaScriptnamed-javascript카탈로그 /Names/JavaScript 이름 트리
ThreatType::UriActionuri-action/S /URI 액션; allowUriActionstrue일 때 억제됨
ThreatType::Xfaxfa/XFA
ThreatType::UnparseableObjectunparseable-object파싱에 실패하는 임의의 객체 또는 카탈로그
ThreatType::StripJavaScriptstrip-javascript옵트인 상위 집합: /JS 키, /S /JavaScript, 또는 /Subtype /JavaScript
ThreatType::StripEmbeddedFilesstrip-embedded-files옵트인: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles, 또는 /EF
ThreatType::StripFormFieldsstrip-form-fields옵트인: /Subtype /Widget, /FT 키, 또는 /AcroForm
ThreatType::StripAnnotationsRichstrip-annotations-rich옵트인 서브타입: Movie, Sound, FileAttachment, 3D, RichMedia, Screen
ThreatType::StripOcgNonDefaultstrip-ocg-non-default옵트인: /Usage 또는 /Visibility 키를 가진 /Type /OCG
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuild옵트인: /Type /Sig, /FT /Sig, /DSS, /VRI, 또는 /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-media옵트인 서브타입: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie

CdrEngine::sanitize는 순서가 정해진 6개 단계를 실행하며 적대적 입력에 대해 결코 예외를 던지지 않습니다.

  1. 파싱. 파싱 실패는 admitted가 false이고 파싱 오류 거부 사유를 담은 결과를 반환합니다. 그 경우 무해화된 출력은 비어 있습니다.
  2. 승인 제어. 객체 수, 집계된 디코딩 스트림 바이트, 스트림별 팽창률, 페이지 수가 정책 한도에 대해 검사됩니다. 한도를 초과하는 문서는 무해화되지 않고 거부됩니다. 거부와 무해화는 구별되어 보고됩니다.
  3. 탐지. ThreatDetector::detect는 정책의 위협 유형에 대해 모든 객체와 트레일러 카탈로그를 스캔합니다. 파싱 불가능한 객체는 건너뛰지 않고 ThreatType::UnparseableObject 발견으로 기록됩니다.
  4. 필터링. 발견을 담은 객체는 제거 대기열에 들어갑니다. 문서 카탈로그는 결코 전체 객체로 제거되지 않습니다. 카탈로그 수준의 발견(OpenAction, AdditionalActions, NamedJavaScript)은 대신 키 스트리핑으로 교정됩니다.
  5. 참조 스크러빙. 제거된 객체에 대한 모든 간접 참조는 직렬화 중에 null로 대체됩니다.
  6. 재구성. CdrRebuilder::rebuild는 번호가 다시 매겨진 객체, 고전적 교차 참조 테이블, 그리고 새로운 트레일러를 갖춘 단일 리비전 %PDF-2.0 파일을 생성합니다. 안전한 스트림 바이트는 바이트 단위로 동일하게 복사됩니다. 재구성된 카탈로그는 /OpenAction, /AA, /Names를 제거하며; /AA는 모든 객체에서 제거됩니다.

반환된 CdrResult는 재구성된 바이트, 제거된 위협 목록, 두 바이트 크기, 승인 플래그, 그리고 거부 사유를 노출합니다. 소스에 해석 가능한 /Root가 있었는데 재구성된 출력이 그것을 잃었다면, 엔진은 구조적으로 손상된 파일을 반환하는 대신 출력을 거부합니다. 이것은 페일 클로즈드 보장입니다: admitted가 true이면 출력이 여전히 문서 카탈로그 참조를 담고 있음을 의미합니다.

증분 업데이트는 결코 살아남지 못합니다: 재구성은 모든 정책 하에서 정확히 하나의 리비전을 직렬화하므로, 섀도 스타일의 늦은 리비전은 구성상 평탄화됩니다. 원본 디지털 서명은 바이트 범위가 더 이상 출력과 일치하지 않으므로 재구성을 거쳐 유효하게 유지될 수 없습니다.

아키텍처 레드라인. CDR은 보안 투영 계층이지 보존 계층이 아닙니다. 출력은 법적 증거 보존, 원본과의 해시 비교, 또는 아카이브 사본에 사용되어서는 안 됩니다.

  • null 정책은 CdrPolicy::standard()로 해석됩니다. 기본의 빈 removeThreatTypes로 구성된 정책은 아무것도 탐지하거나 제거하지 않습니다.
  • allowUriActionstrue로 설정하면 케이스가 removeThreatTypes에 존재하더라도 UriAction 제거를 억제합니다.
  • flattenIncrementalUpdates는 이 릴리스에서 선언적입니다: 재구성은 플래그를 false로 설정하는 permissive()를 포함해 모든 정책 하에서 단일 리비전을 생성합니다.
  • 팽창률 검사는 원시 스트림 길이 0을 1로 취급하므로, 무에서 팽창하는 스트림도 여전히 제한됩니다. 디코딩된 형태가 유지되지 않으면, 원시 스트림 길이가 집계 예산에 산입됩니다.
  • 페이지 수 승인 검사는 최선 노력 방식입니다: 카탈로그나 페이지 트리 읽기 실패가 그 자체로 문서를 거부하지는 않습니다. 객체 수와 압축 해제 예산은 항상 강제됩니다.
  • 원시 스트림 길이가 정수 /Length 항목과 불일치하는 객체는 재구성 시점에 건너뛰어집니다(폴리글롯 방어). 그렇게 건너뛴 객체에 대한 참조는 소스 객체 번호를 유지하며 출력에서 해석되지 않을 수 있습니다. sanitize()는 탐지 가능하게 손상된 결과(누락된 /Root)를 거부하지만, 저수준 CdrRebuilder::rebuild()를 직접 구동하는 호출자는 출력 구조와 참조 무결성을 스스로 재검증해야 합니다.
  • 소스 트레일러가 /ID를 담고 있으면, 재구성된 트레일러는 원본이 아니라 새로 생성된 임의의 /ID를 담습니다. /Info를 포함한 다른 트레일러 항목은 이월되지 않으며; 재구성된 트레일러는 /Size, 해석 가능할 때의 /Root, 그리고 재생성된 /ID를 담습니다.
  • 디코딩된 이름 및 키 바이트는 구분자, 공백, 인쇄 불가능한 바이트에 대해 16진수 이스케이프로 다시 방출되므로, 적대적 이름이 출력에 딕셔너리 구문을 주입할 수 없습니다.
  • 알려진 이름 값 집합 밖의 딕셔너리 키 아래의 문자열 값은 보수적으로 리터럴 문자열로 방출됩니다.
  • CdrPolicy::legacyThreatTypes()는 미래의 어떤 열거형 케이스든 Strip* 케이스로 등록되지 않는 한 기본 제거 대상으로 취급하므로, 새로운 손실 케이스가 기본 정책에 조용히 들어갈 수 없습니다.
  • CDR은 암호 모듈이 아닙니다. 그것의 유일한 무작위성 사용은 재생성된 트레일러 /ID입니다. 서명 검증은 여기서 범위 밖입니다; 서명 심층 레퍼런스를 참조하십시오.
주장표준
ECMAScript 액션을 호출하면 PDF 프로세서가 내장된 스크립트를 실행하게 됩니다.ISO 32000-2§12.6.4.17
JavaScript 이름 트리의 문서 수준 스크립트는 문서가 열릴 때 모두 실행됩니다.ISO 32000-2§12.6.4.17
카탈로그 이름 딕셔너리는 문서 수준 스크립트 액션의 JavaScript 이름 트리를 담을 수 있습니다.ISO 32000-2§7.7.4 (Table 32)
실행 액션은 애플리케이션을 실행하거나, 문서를 열거나 인쇄합니다.ISO 32000-2§12.6.4.6
/AA 추가 액션 딕셔너리는 주석, 페이지, 필드, 그리고 카탈로그의 트리거 이벤트를 확장합니다.ISO 32000-2§12.6.3
신뢰할 수 없는 파일 수집은 들어오는 파일의 존재, 볼륨, 콘텐츠를 제한해야 합니다.OWASP ASVS 5.0§5.2
시스템은 업로드된 파일의 부적절한 실행을 방지하고 위험한 콘텐츠를 탐지해야 합니다.OWASP ASVS 5.0§5.3

모든 절은 의역되었으며; NextPDF는 규범적 텍스트를 재현하지 않습니다. NextPDF는 어떠한 인증 주장도 하지 않습니다. CDR은 구성된 정책 하에 ThreatType으로 열거된 능동 콘텐츠 표면을 제거합니다; 이것은 하나의 기능이며 인증된 무해화 도구가 아닙니다. CDR은 안티바이러스 스캐너가 아니며 멀웨어 시그니처를 탐지하지 않습니다; 그것은 OWASP ASVS 5.4.3 안티바이러스 스캔과 같은 통제를 보완하며 충족하지는 않습니다. 무해화된 파일이 주어진 수집 파이프라인에 수용 가능한지 여부는 운영자의 위험 결정으로 남습니다.

  • 모듈 소스는 @since 1.9.0을 담고 있습니다; 이 레퍼런스는 nextpdf/enterprise 3.1.0으로 출하된 표면을 문서화합니다.
  • 모든 것은 여러분의 호스트에서 인프로세스로 실행됩니다. 무해화 중에 네트워크 접근은 발생하지 않습니다.
  • CdrPolicyDetectedThreatfinal readonly입니다; 한도를 변경하려면 새 정책 인스턴스를 구성하십시오.
  • CdrEngine은 자신의 detector와 rebuilder를 내부적으로 구성합니다. ThreatDetectorCdrRebuilder는 자체 PdfReader를 공급하는 단계별 파이프라인을 위해 직접 사용 가능하게 유지됩니다.
  • CdrRebuilder::rebuild$policy 매개변수는 현재 예약되어 있습니다; 소스는 그것을 호출부 호환성과 향후 정책별 직렬화 조정을 위해 유지된 것으로 문서화합니다.
  • 출력은 구조적으로 재현 가능하지만, 비트 단위로 재현 가능하지는 않습니다: 재생성된 /ID는 소스가 그것을 담고 있었을 때 매 실행마다 다릅니다.
  • 결과 유형 CdrResult(sanitize()의 반환값)는 위에서 동작 측면으로 다루어집니다; 그것의 필드는 public readonly이며, 편의를 위한 hadThreats()threatCount()를 갖습니다.

이 페이지는 외부에서 관찰 가능한 동작과 지원되는 공개 API 표면만을 문서화합니다. 내부 네임스페이스 경로, 헬퍼 클래스, 메커니즘 테이블, 런북 파일명, 그리고 티켓 접두사는 범위 밖입니다.