Bỏ qua để đến nội dung
getnextpdf.com

Enterprise phiên bản

Content Disarm and Reconstruction — Tài liệu tham chiếu chuyên sâu

Trang này là tham chiếu chuyên sâu cho module NextPDF\Enterprise\Security\Cdr. Module khử độc một PDF không tin cậy và tái dựng một tệp sạch từ các đối tượng an toàn của nó. Pipeline gồm: phân tích cú pháp, kiểm soát tiếp nhận, phát hiện mối đe dọa, lọc, chà sạch tham chiếu, tái dựng. Đầu ra là một phép chiếu bảo mật của đầu vào, không bao giờ là một bản sao có giá trị chứng cứ. Để có hướng dẫn về quy trình làm việc, hãy đọc trang năng lực CDR trước.

Năng lực này đi kèm trong NextPDF Enterprise (nextpdf/enterprise) và được kích hoạt bằng một phong bì giấy phép cấp Enterprise. Một triển khai không có quyền này sẽ không nạp các lớp của năng lực. So sánh các phiên bản và nhận giấy phép.

SymbolTham sốHành vi mặc địnhTrả vềNém hoặc thất bại vớiGhi chú
CdrEngine::__constructkhông cóKhởi tạo detector và rebuilder nội bộCdrEngineKhông khai báo gìKhông có collaborator có thể tiêm vào
CdrEngine::sanitizestring $pdfData, ?CdrPolicy $policy = nullChạy toàn bộ pipeline dưới CdrPolicy::standard()CdrResultKhông ném với đầu vào thù địch; lỗi phân tích cú pháp và tiếp nhận trả về một kết quả bị từ chốiKết quả báo cáo việc từ chối tách biệt với việc khử độc
CdrPolicy::__constructbảy tham số có tên tùy chọn, xem khối mãTập loại bỏ rỗng; allowUriActions false; flattenIncrementalUpdates true; giới hạn 100000 đối tượng, 256 MiB đã giải mã, 10000 trang, 1000.0 tỷ lệ phồngCdrPolicyKhông khai báo gìfinal readonly; một danh sách removeThreatTypes rỗng không phát hiện gì
CdrPolicy::standardkhông cóTập mối đe dọa legacy; loại bỏ URI action; giới hạn mặc địnhselfKhông khai báo gìLoại trừ bảy case Strip* gây mất mát
CdrPolicy::paranoidkhông cóTập mối đe dọa legacy với giới hạn chặt hơn: 50000 đối tượng, 128 MiB, 5000 trang, 100.0 tỷ lệ phồngselfKhông khai báo gìLoại trừ bảy case Strip* gây mất mát
CdrPolicy::permissivekhông cóChỉ loại bỏ JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData; giữ lại URI actionselfKhông khai báo gìDùng cho nguồn tin cậy
CdrPolicy::allThreatTypeskhông cóTrả về mọi case ThreatType, bao gồm các case Strip* gây mất mátlist<ThreatType>Không khai báo gìTùy chọn strip tối đa tường minh
CdrPolicy::legacyThreatTypeskhông cóTrả về mọi case ngoại trừ bảy case Strip*list<ThreatType>Không khai báo gìTập loại bỏ mặc định cho standard()paranoid()
CdrPolicy::shouldRemoveThreatType $typeKiểm tra thành viên trong removeThreatTypesboolKhông khai báo gìTrả về false cho UriAction khi allowUriActionstrue
ThreatDetector::detectPdfReader $reader, CdrPolicy $policyQuét mọi đối tượng và catalog trong trailer để tìm các loại mối đe dọa của chính sáchlist<DetectedThreat>Không ném; một đối tượng không phân tích được trở thành mối đe dọa UnparseableObjectQuét catalog bao trùm cây /Names/JavaScript
CdrRebuilder::rebuildPdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policyTuần tự hóa các đối tượng an toàn thành một tệp %PDF-2.0 một-phiên-bảnstringKhông khai báo gì; các đối tượng thất bại khi đọc lại hoặc kiểm tra /Length sẽ bị bỏ qua$policy được dành cho các tinh chỉnh tuần tự hóa trong tương lai
DetectedThreat::__constructThreatType $type, int $objectNumber, string $description, string $location = ''Đối tượng giá trị phát hiện bất biếnDetectedThreatKhông khai báo gìCả bốn thuộc tính đều là public readonly
ThreatTypeenum nền chuỗiHai mươi case: mười ba legacy cộng bảy case Strip* opt-inn/an/aXem danh mục case bên dưới
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

Mười ba case legacy hình thành tập loại bỏ mặc định. Các case Strip* gây mất mát theo thiết kế và không bao giờ vào một chính sách mặc định.

CaseGiá trị nềnBề mặt phát hiện
ThreatType::JavaScriptjavascriptKhóa /JS trên bất kỳ đối tượng nào, hoặc một action /S /JavaScript
ThreatType::AdditionalActionsadditional-actionsTừ điển /AA trên bất kỳ đối tượng nào
ThreatType::OpenActionopen-actionKhóa /OpenAction trên bất kỳ đối tượng nào
ThreatType::LaunchActionlaunch-actionAction /S /Launch
ThreatType::RemoteGoToremote-gotoAction /S /GoToR hoặc /S /GoToE
ThreatType::SubmitFormsubmit-formAction /S /SubmitForm
ThreatType::ImportDataimport-dataAction /S /ImportData
ThreatType::EmbeddedFilesembedded-filesCây tên /EmbeddedFiles hoặc từ điển /EF
ThreatType::RichMediarich-media/Subtype /RichMedia
ThreatType::NamedJavaScriptnamed-javascriptCây tên /Names/JavaScript của catalog
ThreatType::UriActionuri-actionAction /S /URI; bị chặn khi allowUriActionstrue
ThreatType::XfaxfaKhóa /XFA
ThreatType::UnparseableObjectunparseable-objectBất kỳ đối tượng hoặc catalog nào phân tích cú pháp thất bại
ThreatType::StripJavaScriptstrip-javascriptSiêu tập opt-in: khóa /JS, /S /JavaScript, hoặc /Subtype /JavaScript
ThreatType::StripEmbeddedFilesstrip-embedded-filesOpt-in: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles, hoặc /EF
ThreatType::StripFormFieldsstrip-form-fieldsOpt-in: /Subtype /Widget, khóa /FT, hoặc khóa /AcroForm
ThreatType::StripAnnotationsRichstrip-annotations-richCác subtype opt-in: Movie, Sound, FileAttachment, 3D, RichMedia, Screen
ThreatType::StripOcgNonDefaultstrip-ocg-non-defaultOpt-in: /Type /OCG với một khóa /Usage hoặc /Visibility
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuildOpt-in: /Type /Sig, /FT /Sig, /DSS, /VRI, hoặc /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-mediaCác subtype opt-in: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie

CdrEngine::sanitize thực thi sáu pha có thứ tự và không bao giờ ném với đầu vào thù địch.

  1. Phân tích cú pháp. Một lỗi phân tích cú pháp trả về một kết quả với admitted false và một lý do từ chối do lỗi phân tích. Đầu ra đã khử độc rỗng trong trường hợp đó.
  2. Kiểm soát tiếp nhận. Số lượng đối tượng, tổng số byte stream đã giải mã, tỷ lệ phồng trên từng stream, và số trang được kiểm tra so với các giới hạn của chính sách. Một tài liệu vượt giới hạn bị từ chối, không được khử độc. Việc từ chối và việc khử độc được báo cáo tách biệt.
  3. Phát hiện. ThreatDetector::detect quét mọi đối tượng và catalog trong trailer để tìm các loại mối đe dọa của chính sách. Các đối tượng không phân tích được được ghi nhận là các phát hiện ThreatType::UnparseableObject thay vì bị bỏ qua.
  4. Lọc. Các đối tượng mang phát hiện được xếp hàng để loại bỏ. Catalog của tài liệu không bao giờ bị loại bỏ như một đối tượng nguyên khối. Các phát hiện ở cấp catalog (OpenAction, AdditionalActions, NamedJavaScript) được khắc phục bằng cách bóc khóa thay vào đó.
  5. Chà sạch tham chiếu. Mọi tham chiếu gián tiếp đến một đối tượng đã bị loại bỏ được thay bằng null trong quá trình tuần tự hóa.
  6. Tái dựng. CdrRebuilder::rebuild phát ra một tệp %PDF-2.0 một-phiên-bản với các đối tượng được đánh số lại, một bảng tham chiếu chéo cổ điển, và một trailer mới. Các byte stream an toàn được sao chép byte-trùng-khớp. Catalog được tái dựng bỏ /OpenAction, /AA, và /Names; /AA bị bỏ khỏi mọi đối tượng.

CdrResult được trả về phơi bày các byte đã tái dựng, danh sách mối đe dọa đã loại bỏ, cả hai kích thước byte, cờ tiếp nhận, và lý do từ chối. Nếu nguồn có một /Root phân giải được và đầu ra tái dựng mất nó, engine từ chối đầu ra thay vì trả về một tệp bị hỏng cấu trúc. Đây là một bảo đảm fail-closed: admitted true hàm ý đầu ra vẫn mang một tham chiếu catalog tài liệu.

Các bản cập nhật tăng dần không bao giờ tồn tại: quá trình tái dựng tuần tự hóa đúng một phiên bản dưới mọi chính sách, nên các phiên bản trễ kiểu bóng (shadow) bị làm phẳng bởi cấu trúc. Chữ ký số gốc không thể vẫn hợp lệ qua một lần tái dựng, vì các byte range không còn khớp với đầu ra.

Lằn ranh đỏ về kiến trúc. CDR là một lớp chiếu bảo mật, không phải một lớp bảo tồn. Đầu ra không được dùng để bảo tồn chứng cứ pháp lý, so sánh hash với bản gốc, hoặc làm bản sao lưu trữ.

  • Một chính sách null phân giải thành CdrPolicy::standard(). Một chính sách được khởi tạo với removeThreatTypes rỗng mặc định sẽ phát hiện và loại bỏ không gì cả.
  • Đặt allowUriActions thành true chặn việc loại bỏ UriAction ngay cả khi case đó hiện diện trong removeThreatTypes.
  • flattenIncrementalUpdates mang tính khai báo trong bản phát hành này: quá trình tái dựng phát ra một phiên bản duy nhất dưới mọi chính sách, bao gồm permissive(), vốn đặt cờ này thành false.
  • Kiểm tra tỷ lệ phồng coi độ dài stream thô bằng không như một, nên một stream phồng lên từ hư vô vẫn bị chặn giới hạn. Khi không giữ lại dạng đã giải mã nào, độ dài stream thô được tính vào ngân sách tổng.
  • Kiểm tra tiếp nhận theo số trang là nỗ-lực-tốt-nhất: một lỗi đọc catalog hoặc cây trang không tự nó từ chối tài liệu. Ngân sách số lượng đối tượng và giải nén luôn được thực thi.
  • Một đối tượng có độ dài stream thô không khớp với mục /Length số nguyên của nó sẽ bị bỏ qua tại thời điểm tái dựng (phòng thủ polyglot). Một tham chiếu đến đối tượng bị bỏ qua như vậy giữ lại số đối tượng nguồn của nó và có thể không phân giải được trong đầu ra. sanitize() từ chối các kết quả hỏng có thể phát hiện được (một /Root bị thiếu), nhưng một caller điều khiển trực tiếp CdrRebuilder::rebuild() cấp thấp phải tự tái xác thực cấu trúc đầu ra và tính toàn vẹn tham chiếu.
  • Khi trailer nguồn mang /ID, trailer được tái dựng mang một /ID ngẫu nhiên được sinh mới, không phải bản gốc. Các mục trailer khác, bao gồm /Info, không được mang theo; trailer được tái dựng giữ /Size, /Root khi phân giải được, và /ID được sinh lại.
  • Các byte tên và khóa đã giải mã được phát lại với các escape thập lục phân cho các dấu phân cách, khoảng trắng, và các byte không in được, nên các tên thù địch không thể tiêm cú pháp từ điển vào đầu ra.
  • Các giá trị chuỗi dưới các khóa từ điển nằm ngoài tập được biết là mang-giá-trị-tên được phát ra một cách thận trọng như các chuỗi văn tự.
  • CdrPolicy::legacyThreatTypes() coi bất kỳ case enum tương lai nào là loại-bỏ-mặc-định trừ khi nó được đăng ký như một case Strip*, nên các case gây mất mát mới không thể âm thầm vào các chính sách mặc định.
  • CDR không phải là một module mật mã. Việc sử dụng ngẫu nhiên duy nhất của nó là /ID trailer được sinh lại. Xác thực chữ ký nằm ngoài phạm vi ở đây; xem Tham chiếu chuyên sâu về chữ ký.
Tuyên bốTiêu chuẩnĐiều khoản
Kích hoạt một ECMAScript action khiến một bộ xử lý PDF thực thi script được nhúng.ISO 32000-2§12.6.4.17
Các script cấp tài liệu trong cây tên JavaScript đều thực thi khi tài liệu mở.ISO 32000-2§12.6.4.17
Từ điển tên của catalog có thể giữ một cây tên JavaScript của các script action cấp tài liệu.ISO 32000-2§7.7.4 (Table 32)
Một launch action khởi chạy một ứng dụng, hoặc mở hoặc in một tài liệu.ISO 32000-2§12.6.4.6
Các từ điển additional-actions /AA mở rộng các sự kiện kích hoạt trên annotation, trang, trường, và catalog.ISO 32000-2§12.6.3
Việc tiếp nhận tệp không tin cậy phải chặn giới hạn sự hiện diện, khối lượng, và nội dung của các tệp đến.OWASP ASVS 5.0§5.2
Các hệ thống nên ngăn việc thực thi không phù hợp các tệp được tải lên và phát hiện nội dung nguy hiểm.OWASP ASVS 5.0§5.3

Tất cả điều khoản đều được diễn giải; NextPDF không tái tạo văn bản quy phạm. NextPDF không đưa ra tuyên bố chứng nhận nào. CDR loại bỏ các bề mặt nội dung chủ động được liệt kê bởi ThreatType dưới chính sách được cấu hình; nó là một năng lực, không phải một bộ khử độc được chứng nhận. CDR không phải là một trình quét virus và không phát hiện chữ ký malware; nó bổ sung cho, và không thỏa mãn, các kiểm soát như quét virus của OWASP ASVS 5.4.3. Liệu một tệp đã khử độc có chấp nhận được cho một pipeline tiếp nhận nhất định hay không vẫn là quyết định rủi ro của người vận hành.

  • Mã nguồn module mang @since 1.9.0; tham chiếu này ghi lại bề mặt như đã đi kèm trong nextpdf/enterprise 3.1.0.
  • Mọi thứ chạy trong tiến trình trên host của bạn. Không có truy cập mạng nào xảy ra trong quá trình khử độc.
  • CdrPolicyDetectedThreatfinal readonly; hãy khởi tạo một thực thể chính sách mới để thay đổi giới hạn.
  • CdrEngine khởi tạo detector và rebuilder của nó nội bộ. ThreatDetectorCdrRebuilder vẫn dùng được trực tiếp cho các pipeline theo giai đoạn cung cấp PdfReader riêng của chúng.
  • Tham số $policy của CdrRebuilder::rebuild hiện được dành riêng; mã nguồn ghi lại rằng nó được giữ để tương thích với call-site và cho các tinh chỉnh tuần tự hóa theo-chính-sách trong tương lai.
  • Đầu ra có thể tái lập về cấu trúc, không phải về bit: /ID được sinh lại khác nhau ở mỗi lần chạy khi nguồn có mang nó.
  • Kiểu kết quả CdrResult (giá trị trả về của sanitize()) được bao trùm theo hành vi ở trên; các trường của nó là public readonly, với hadThreats()threatCount() như các tiện ích.

Trang này ghi lại hành vi có thể quan sát được từ bên ngoài và bề mặt API công khai được hỗ trợ mà thôi. Các đường dẫn namespace nội bộ, các lớp trợ giúp, các bảng cơ chế, các tên tệp runbook, và các tiền tố ticket nằm ngoài phạm vi.