İçeriğe geç
getnextpdf.com

Güvenilmeyen PDF'leri temizleme: içerik etkisizleştirme ve yeniden inşa

Spec: ISO 32000-2, §12.6.4

Dış dünyadan gelen bir PDF, bir belge olduğu kadar koddur da. JavaScript, bir Launch eylemi, gömülü bir yürütülebilir ve bir ayrıştırıcıyı yanıltmak için tasarlanmış bir yapı taşıyabilir. Content Disarm & Reconstruction (CDR), o dosyayı güvenilmeyen kabul eder, yalnızca güvenli olanı tutar ve sağ kalanlardan temiz bir PDF yeniden inşa eder.

Bu sayfa, NextPDF Enterprise’ın CdrEngine’inin bunu nasıl yaptığını açıklar — ve her CDR satıcısının yüksek sesle söylemesi gereken o tek dürüst şeyi: yeniden inşa edilen dosya, özgün dosyanın bir güvenlik izdüşümüdür, sadık bir kopyası değil.

Bir PDF’nin tehlikeli kısımları egzotik değildir. Standart özelliklerdir. Belirtim, bir bütün eylemler kataloğu tanımlar — bir belge açıldığında, bir sayfa gösterildiğinde, bir alan değiştiğinde ne olduğu — ve o katalog JavaScript ile Launch eylemlerini içerir (Spec: ISO 32000-2, §12.6.4). Biçimi onurlandıran bir görüntüleyici onları seve seve çalıştırır. İşte saldırganın dayanağı budur: aynı anda hem kusursuzca geçerli hem de kusursuzca kötü niyetli bir dosya.

Dosya uzantısına göre filtrelemek burada hiçbir işe yaramaz. Tehdit, iyi biçimlenmiş bir PDF’nin içindedir; bu yüzden tek gerçek savunma, onu açmak, anlamak ve etkin makineyi, bir oluşturucuya ulaşmadan önce soymaktır. Bu, OWASP’ın dosya-yükleme ve girdi-doğrulama yönlendirmesinin tarif ettiği girdi-doğrulama duruşudur: byte’lara asla güvenme ve düşman bir eseri bilinen-kötü imzalar için taramaktansa bilinen-iyi bir eseri yeniden inşa etmeyi yeğle.

  • CDR, girdinin düşman olduğunu varsayar ve eskisini yamamak yerine yeni bir dosya üretir.
  • CdrEngine::sanitize() altı evre çalıştırır: ayrıştırma, kabul denetimi, tehdit tespiti, filtre, referans ovalama, yeniden inşa.
  • Neyin kaldırıldığını, belgenin kabul edilip edilmediğini ve — edilmediyse — neden reddedildiğini söyleyen bir CdrResult döndürür.
  • Çıktı bir güvenlik izdüşümüdür. Açıkça bir kanıt kopyası, bir özet eşleşmesi ya da bir arşiv eseri değildir. Bu bir uyarı değil, bir sözleşmedir.
  • Bu yalnızca Enterprise’dadır. NextPDF çekirdeği CDR gerçekleştirmez.

Motorun kendi belgeleri, tasarım kırmızı çizgisini üç sözcükle belirtir: Security Projection Layer. sanitize(), yıkıcı, geri-döndürülemez bir dönüşümdür. Byte’ları atmaya izinlidir. İzinli olmadığı şey, sonucun aynı belge olduğunu iddia etmektir.

Hat bilinçli olarak sıralanmıştır. Her evre, bir sonraki evre üzerinde harekete geçmeden önce güveni daraltır.

  1. ParsePdfReader builds the object graph from the raw bytes. A parse failure is a rejection, not a best-effort guess.
  2. Admission controlResource limits are checked first — object count, page count, decoded-stream size, per-stream inflation ratio. Over-budget input is rejected, never sanitised.
  3. DetectThreatDetector walks the graph and records each dangerous feature as a DetectedThreat with its object number and type.
  4. FilterObjects are partitioned into safe and removed. Catalog-level keys are stripped in place so the document catalog itself survives.
  5. Reference scrubPointers to removed objects are cleaned so the rebuilt file has no dangling references.
  6. RebuildCdrRebuilder serialises only the safe objects into a new PDF. The output is fresh structure, not an edited original.
The six phases of CdrEngine::sanitize(), in order. The document is parsed, then admitted or rejected against resource limits, then scanned for threats; dangerous objects are filtered out, dangling references are scrubbed, and only the surviving safe objects are serialised into a brand-new PDF. The original bytes never carry through.

Etkisizleştirmeden önce kabul. Tek bir tehdit kaldırılmadan önce, motor belgenin işlenmeye değer olup olmadığını sorar. CdrPolicy sınırları taşır — maxObjects, maxPageCount, maxDecodedStreamBytes ve sıkıştırma bombalarına karşı savunan bir maxInflationRatio. Bunları aşan bir belge reddedilir ve CdrResult bunu admitted: false ve bir rejectionReason ile söyler. Bu ayrım yük taşır: “onu temizledik” ve “onu reddettik” farklı sonuçlardır ve sonuç tipi onları ayrı tutar ki hata raporlamanız da ayrı tutabilsin.

Tehditler adlandırılır, tahmin edilmez. ThreatDetector::detect(), her tehlikeli yapıyı bir ThreatType’a eşler — JavaScript, LaunchAction, OpenAction, AdditionalActions, RemoteGoTo, SubmitForm, ImportData, EmbeddedFiles, RichMedia, NamedJavaScript ve daha fazlası — her biri belirli bir PDF özelliğine bağlı. Hiç ayrıştırılamayan bir nesne, kendi tehdit tipi olan UnparseableObject’e dönüşür; çünkü temizleyicinin okuyamadığı bir nesne, kefil olamayacağı bir nesnedir. Her bulgu, suçlu nesne numarasını taşıyan bir DetectedThreat’tir; böylece kaldırma kesindir.

Kaldırma yalnızca yükü değil, belgeyi de korur. Bazı tehlikeli anahtarlar belge kataloğunda (Root) yaşar — örneğin, açılışta tetiklenen bir /OpenAction. Bir anahtarı öldürmek için tüm Root nesnesini kaldırmak, kataloğu yok eder ve dosyayı sessizce bozar. Motor, bunları bunun yerine katalog üzerinde yerinde anahtar soymaları olarak ele alır ve bir kapalı-başarısız koruması olarak, /Root’unu tümden yitirmiş bir yeniden inşa edilmiş belge üretmeyi reddeder. Başarı raporlarken yapısal olarak bozuk bir dosya üreten bir temizleyici, tam olarak bu korumanın önlemek için var olduğu başarısızlık kipidir.

Aşağıdaki şekil gerçek giriş noktasıdır. Motora ham byte’lar ve bir politika verirsiniz; karşılığında ne olduğu hakkında dürüst bir CdrResult alırsınız.

<?php
declare(strict_types=1);
use NextPDF\Enterprise\Security\Cdr\CdrEngine;
use NextPDF\Enterprise\Security\Cdr\CdrPolicy;
$engine = new CdrEngine();
// Standard policy removes the known active threats — JavaScript, Launch
// actions, remote go-to, form submit/import, and the rest — while leaving
// the lossy opt-in "Strip*" cases off by default.
$result = $engine->sanitize($untrustedPdfBytes, CdrPolicy::standard());
if (!$result->admitted) {
// Rejected by admission control (e.g. object/page limit, zip bomb).
// This is NOT a sanitised document. Do not serve it; report the reason.
throw new \RuntimeException($result->rejectionReason);
}
if ($result->hadThreats()) {
// The disarmed bytes are safe to render. Each removed threat carries its
// type and object number for your audit log — never silently.
foreach ($result->removedThreats as $threat) {
error_log(\sprintf(
'CDR removed %s in object %d',
$threat->type->value,
$threat->objectNumber,
));
}
}
$cleanBytes = $result->sanitizedPdf; // The security projection. Not the original.

Bu kodun, hâlâ tehlikeli bir dosyayı sessizce geri verdiği hiçbir yol yoktur. Ya belge kabul edilir ve etkisizleştirilir ya da belirtilmiş bir nedenle reddedilir. removedThreats listesi, etkisizleştirmenin sihirli değil, denetlenebilir olduğu anlamına gelir.

“CDR, fazladan adımlı redaksiyondan başka bir şey değil.”

Değildir ve ikisini birbirine karıştırmak tehlikelidir. Redaksiyon bilgiyi kaldırır — adları, hesap numaralarını, bir insanın görmemesi gereken içeriği. CDR yeteneği kaldırır — bir makinenin çalıştırmaması gereken JavaScript’i, Launch eylemini, gömülü yükü. Karşıt başarı ölçütleri vardır. Bir redaksiyon, hassas içerik gittiğinde ve gerisi aynen korunduğunda doğrudur. Bir etkisizleştirme, tehdit gittiğinde doğrudur ve oraya varmak için iyi huylu yapıyı değiştirmeye gönülden razıdır. Niyetinize uyan aracı kullanın; birinden, diğerinin güvencelerini bekleyerek tutunmayın.

İkinci bir yanlış kanı, temiz bir yeniden inşanın özgünün temiz olduğunu kanıtladığıdır. Özgün hakkında hiçbir şey kanıtlamaz. Yalnızca çıktının tespit edilen hiçbir tehdit içermediğini kanıtlar. Girdi bir silah olabilirdi; CDR’nin işi, aşağı yönde ilettiğiniz şeyin öyle olmadığından emin olmaktır.

Bu, broşürlerin atladığı kısımdır; bu yüzden onu açıkça söyleyeceğiz.

  • Çıktı bir güvenlik izdüşümüdür, bir kanıt kopyası değil. CdrEngine kaynağı bunu mimari bir kırmızı çizgi olarak taşır. Temizlenmiş PDF, hukuki kanıt saklama için, özgüne karşı özet karşılaştırması için ya da bir arşiv kopyası olarak kullanılmamalıdır. Dönüşüm, tasarım gereği yıkıcı ve geri-döndürülemezdir.
  • Tespitin bir kapsamı vardır. CDR, adlandırmayı bildiği tehditleri kaldırır. Bir derinlemesine-savunma yığınında güçlü, denetlenebilir bir katmandır — bir dosyanın olası her gelecek tekniğinden arınmış olduğunun garantisi değil. Onu, OWASP’ın dosya-yükleme yönlendirmesinin tarif ettiği aynı yükleme doğrulamasının, içerik-tipi denetimlerinin ve en-az-ayrıcalık ele alımının arkasında tutun.
  • Bazı politikalar kasıtlı olarak kayıplıdır. İsteğe bağlı Strip* durumları gömülü dosyaları, imzaları, form alanlarını, katmanları ve 3B medyayı kaldırır. Bunlar güçlüdür ve meşru içeriği silerler — örneğin, bir ZUGFeRD/Factur-X fatura yükünü. Tam da bu nedenle varsayılan olarak kapalıdırlar. Onları bilerek açın.
  • İmzalar bir yeniden inşadan sağ çıkmaz. Dosyayı yeniden inşa etmek byte’larını değiştirir; bu yüzden herhangi bir özgün dijital imza artık byte aralığıyla eşleşmez. Etkisizleştirilmiş bir belge, kaynağa göre imzasızdır. İmzalı bir esere ihtiyacınız varsa, temiz çıktıyı yeni bir eylem olarak imzalayın.
Content Disarm & Reconstruction (CDR) — edition availability
EditionAvailability
Core

Not available. NextPDF core does not perform CDR. It parses, renders, and writes PDFs; it does not threat-detect or rebuild untrusted input.

Pro

Not available in the Pro edition.

Enterprise

Available via CdrEngine. The disarmed output is a security projection of the source — it must not be treated as an evidentiary, hash-comparable, or archival copy of the original.

  • CDR (Content Disarm & Reconstruction) — güvenilmeyen bir dosyayı ayrıştıran, etkin ya da tehlikeli bileşenleri kaldıran ve güvenli kalandan temiz bir dosya yeniden inşa eden bir temizleme stratejisi; bilinen-kötü imzalar için tarama yerine.
  • Güvenlik izdüşümü (security projection) — tehditlerin kaldırılmasını garanti ederken, yararlı olacak kadar kaynağı koruyan, temizlenmiş bir çıktı. Bilinçli olarak byte-sadık değildir ve kanıt, özetleme ya da arşivleme için uygun değildir.
  • Kabul denetimi (admission control) — herhangi bir etkisizleştirme işi başlamadan önce, kaynak sınırlarını (nesne sayısı, sayfa sayısı, çözülmüş-akış boyutu, şişme oranı) aşan belgeleri reddeden, temizleme-öncesi kapı.
  • Eylem (action) — belge-açılışı ya da bir alan değişikliği gibi bir tetikleyicide bir şeyin olmasına yol açan bir PDF yapısı; eylem-tipi kataloğu (Spec: ISO 32000-2, §12.6.4), kanonik CDR tehdit yüzeyi olan JavaScript ve Launch eylemlerini içerir.
  • Sarkan referans (dangling reference) — filtreleme sonrası artık var olmayan bir nesneye işaret eden bir işaretçi. Referans-ovalama evresi, yeniden inşa edilen dosyanın yapısal olarak tutarlı kalması için bunları kaldırır.