İçeriğe geç

Güvenlik ve işletim

Bu köprü, HTML’inizi bir ağ sınırı üzerinden bir tarayıcı motoruna gönderir. Bu sayfa, kaynak kodu doğruluk kaynağı olarak kabul ederek bu sınırı koruyan denetimleri belgeler. Bir denetim bir standarda atıf yapıyorsa, bu atıf kodun belge bloğunda bildirilen atıftır. Bu sayfa kodun ileri sürdüğünü yeniden ifade eder; normatif metni yeniden üretmez.

Paketin belge blokları, savunma yaptığı tehditleri adlandırır:

  • XSS-to-PDF — PDF işleme sırasında çalışan kötü niyetli işaretleme yoluyla siteler arası betik çalıştırma (XSS).
  • SSRF — Bir iç adrese istek gönderen işaretleme veya hedef URL’nin neden olduğu sunucu taraflı istek sahteciliği (SSRF).
  • Kaynak tükenmesi — Aşırı büyük girdi veya bir açma bombası.
  • DNS yeniden bağlama — Bir ana makine adının doğrulamadan geçip ardından bağlantı anında özel bir adrese çözümlendiği Etki Alanı Adı Sistemi (DNS) yeniden bağlama.
  • Yol üzerinde TLS dinlemesi — Worker’a giden yol üzerinde değiştirilmiş bir sertifika yoluyla gerçekleştirilen yol üzerinde Taşıma Katmanı Güvenliği (TLS) dinlemesi.

Aşağıda her tehdit için belirli ve test edilebilir bir denetim yer alır.

Girdi denetimleri (istek PHP’den ayrılmadan önce)

“Girdi denetimleri (istek PHP’den ayrılmadan önce)” başlıklı bölüm

CloudflareSecurityPolicy::validate() herhangi bir istek oluşturulmadan önce çalışır:

DenetimDavranışSınır kaynağı
Boyut üst sınırıBoyutu şu değerden büyük olan HTML’yi reddeder: maxHtmlSizeCloudflareRendererConfig, varsayılan 5000000 bayt
Base64 açma-bombası korumasıHer data:…;base64,… URI’sinin çözülmüş boyutunu tahmin eder; üst sınırda veya üzerindeki değerleri reddederMAX_DATA_URI_BYTES = 13631488
Meta-yenileme yasağıBüyük-küçük harf duyarsız biçimde her <meta http-equiv="refresh"> öğesini reddederŞunun içindeki düzenli ifade: CloudflareSecurityPolicy

Bir ihlal, sorunlu değeri ve sınırı belirten bir iletiyle birlikte RuntimeException oluşturur. Meta-yenileme yasağı uygulanır; çünkü bir yenileme yönergesi Worker’ın işlediği sayfa içinde gezinmeyi başlatabilir — bu, URL’de değil, içerikte yer alan bir SSRF vektörüdür.

HTML güvenlik ilkesi nextpdf/core paketinden gelir (HtmlSecurityPolicyInterface, varsayılan DefaultHtmlSecurityPolicy); ayrıştırma katmanında çalışır ve yukarıdaki taşıma katmanı denetimlerini tamamlar. Bunu getHtmlSecurityPolicy() ile alın. Özel bir ilkeyi yapıcı aracılığıyla ekleyin.

CloudflareSecurityPolicy::validateWorkerUrl():

  1. Ayrıştırılamayan veya scheme/host içermeyen bir URL’yi reddeder (Invalid Worker URL).
  2. HTTPS dışındaki her şemayı reddeder (Worker URL must use HTTPS).
  3. IP değişmezi olan bir ana makine için, özel veya ayrılmış aralıkları şu bayraklarla reddeder: PHP’nin FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE bayrakları. Uygulamada bu, RFC 1918 özel alanını, geri döngüyü ve RFC 3927 bağlantı yerel adreslerini reddeder. Testler açıkça 192.168.x, 127.0.0.1 ve 169.254.x değerlerinin reddedilmesini kapsar. Aralık üyeliğine PHP’nin filtre uzantısı karar verir; bu paket o kararı belirli bir maddeye sabitlemez. RFC 1918 ve RFC 3927, burada bu aralıkların iyi bilinen tanımları olarak betimleyici biçimde adlandırılmıştır.
  4. Bir ana makine adı için, tüm A ve AAAA kayıtlarını dns_get_record() ile çözümler (yalnızca ilk yanıtı döndüren gethostbyname() değil) ve çözümlenen herhangi bir adres özel veya ayrılmışsa ana makineyi reddeder.

Tüm kayıtların çözümlenmesi bilinçli bir tercihtir. Sınıfın belge bloğu bunu, birden çok kayıt döndüren bir ana makineye karşı bir savunma olarak belgeler; bu durumda tek kayıt döndüren bir arama genel adresi seçebilirken sonraki bağlantı özel bir adresi seçebilir. Bu, OWASP SSRF Prevention Cheat Sheet ile uyumludur: etki alanı için hem A hem de AAAA yanıtlarını çözümleyin ve genel olmayan adres denetimini sonuç kümesinin tamamına uygulayın.

validateWorkerUrl(), denetlenmiş IP kümesini döndürür. İşleyici, gönderimden hemen önce assertPinsStillValid() öğesini çağırır. Bu çağrı, ana makineyi yeniden çözümler ve yeni görülen bir IP’yi reddeder (Worker URL DNS answer changed since validation — possible DNS rebinding attack). Bu, doğrulama ile bağlantı arasındaki denetim-zamanı / kullanım-zamanı penceresini kapatır.

Denetlenmiş bir IP kümesi veya bir Konu Genel Anahtarı Bilgisi (SPKI) sabitleme kümesi mevcut olduğunda ve bir PHP Standartları Önerisi 17 (PSR-17) ResponseFactory sağlandığında, işleyici enjekte edilen PHP Standartları Önerisi 18 (PSR-18) istemcisi yerine Transport\PinnedCurlTransport kullanır. Taşıma katmanı bu denetimleri cURL tutamacı katmanında uygular:

  • Sabitlenmiş DNSCURLOPT_RESOLVE, host:port değerini denetlenmiş IP kümesine bağlar, böylece libcurl bağlantı anında kendi çözümlemesini gerçekleştirmez. Bu bağlama, kullanıcı alanındaki DNS denetiminin gerçek bağlantıya uygulanmasını sağlar; bu olmadan libcurl farklı bir adresi çözümleyebilir.
  • TLS genel anahtar sabitlemeCURLOPT_PINNEDPUBLICKEY, birleştirilmiş sabitleme kümesinden ayarlanır. Bu, RFC 7469 §2.6’yı izler: sabitlenmiş bir bağlantı, sunucunun sunduğu SPKI parmak izi kümesi, yapılandırılan sabitleme kümesiyle kesiştiğinde kabul edilir ve bir sabitleme doğrulaması başarısızlığı kurtarılamaz niteliktedir. Sabitleme dizeleri sha256/<base64> biçiminden cURL’ün sha256//<base64> biçimine normalleştirilir; hatalı biçimli bir sabitleme InvalidSpkiPinException oluşturur.
  • TLS doğrulaması açıkCURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2.
  • Otomatik yönlendirme yokCURLOPT_FOLLOWLOCATION => false, CURLOPT_MAXREDIRS => 0. Bir 3xx yanıtı, libcurl tarafından denetlenmemiş bir ana makineye izlenmek yerine ilke katmanına iletilir. Sınıfın belge bloğu, bunun bilinçli bir tercih olduğunu belirtir; böylece yönlendirmeler sessizce izlenmek yerine yeniden doğrulanır.
  • Kesin zaman aşımıCURLOPT_TIMEOUT, renderTimeout değerinden ayarlanır (varsayılan 30 saniye).

Bir cURL hatası veya dize olmayan bir yanıt gövdesi, cURL hata numarası ve iletisiyle birlikte CloudflareRenderException oluşturur.

Yapılandırma, pinnedPublicKeys ve ayrı bir backupPublicKeys içerir. RFC 7469 §2.5, bir yedek sabitlemeyi, çevrimdışı tutulan ve henüz dağıtılmamış ikincil bir anahtar çiftine ait parmak izi olarak tanımlar ve bunu, kazara oluşan sabitleme doğrulaması başarısızlığı için birincil kurtarma yolu olarak ele alır. Sertifika döndürmesinin uç noktayı kullanılamaz duruma getirmemesi için en az bir yedek sabitleme bulundurun. Ayrı alan, döndürmeyi bağımsız olarak doğrulamanıza olanak tanır. İşletimsel olarak:

  • Yaprak sertifikanın veya döndürmesini denetlediğiniz bir ara sertifikanın SPKI’sini sabitleyin.
  • Döndürme işleminden önce her zaman sonraki sertifika için bir yedek sabitleme yapılandırın.
  • Boş bir sabitleme kümesi, sabitlemeyi devre dışı bırakır; bunu yalnızca kararlı ve bilinen bir sertifika zinciriyle kullanın. Sabitleme, yapılandırma yoluyla isteğe bağlı olarak etkinleştirilir.
  • Worker isteği Authorization: Bearer <apiToken> içerir. apiToken bir #[SensitiveParameter] olduğundan, yığın izlerinde gizlenir. Erişilebilirlik yoklaması, aynı taşıyıcı üst bilgisini bir Hiper Metin Aktarım Protokolü (HTTP) HEAD isteğinde gönderir.
  • Cloudflare R2 erişim anahtarları (accessKeyId, secretAccessKey) birer #[SensitiveParameter] olup yalnızca Amazon Web Services (AWS) İmza V4 imzalama anahtarını türetmek için kullanılır.
  • ApiKeyValidator anahtarları hash_equals() ile (zamanlama açısından güvenli) karşılaştırır ve validateHashed() aracılığıyla Güvenli Karma Algoritması 256 (SHA-256) ile karma biçiminde anahtar depolamayı destekler.
  • Yapılandırma nesneleri final readonly niteliğindedir — bir kez ayarlanmış bir gizli bilgi değiştirilemez.
  • Gizli bilgileri ortam değişkenlerinden veya bir gizli bilgi yöneticisinden alın. Bunları asla işlemeyin. Paket, daha geniş NextPDF güvenlik temel hattını izler: PHPStan Level 10, her dosyada declare(strict_types=1), eval()/exec() kullanımı yok, SHA’ya sabitlenmiş GitHub Actions.
  • Hiçbir Cloudflare platform sınırı tanımlamaz (Worker CPU süresi, bellek, istek gövdesi üst sınırı veya alt istek sayısı). Bu belgelerde belirtilen tek boyut ve süre sınırları, paketin kendisinin uyguladığı sınırlardır; bunlar yukarıda ve /integrations/cloudflare/configuration/. içinde listelenmiştir. Platform sınırları için Cloudflare’ın resmi belgelerine ve Worker’ınızın kendi uygulamasına başvurun.
  • PDF imzalamaz ve imza uygunluğuyla ilgili hiçbir iddiada bulunmaz. İmzalar gerektiğinde, burada işleyin, ardından motorla imzalayın. NextPDF Pro yalnızca PDF Gelişmiş Elektronik İmzalar (PAdES) B-B imzalama sağlar; uzun süreli doğrulama profilleri bir Enterprise yeteneğidir ve bu köprünün kapsamı dışındadır.
  • İşlem hattını onaylamaz, garanti etmez veya “kurcalanamaz” kılmaz. Yalnızca bu sayfada açıklanan belirli, kaynaktan doğrulanabilir denetimleri uygular.
Belirtiİlk denetim
Worker URL must use HTTPSYapılandırılan workerUrl şemasını denetleyin.
private or reserved IPWorker ana makine adının DNS kayıtlarını denetleyin; RFC 1918 / geri döngü / RFC 3927 alanına çözümlenen bir kayıt arayın.
DNS answer changed since validationDNS kararsızlığı veya bir yeniden bağlama girişimi; yeniden çözümleyin ve kayıt kümesinin tamamını inceleyin.
cURL transport errorAğ yolunu, TLS zincirini ve — sabitlemeler ayarlanmışsa — sunulan sertifikanın SPKI’sinin hâlâ sabitleme kümesinde olup olmadığını denetleyin.
Bir sertifika döndürmesinden hemen sonra işlemeler başarısız oluyorSabitleme kümesinde eşleşen bir yedek sabitleme yok. Döndürmeden önce yeni SPKI’yi bir yedek olarak ekleyin.
is not installed / no LocalRendererFactoryInterfaceYedek mekanizma etkin ancak hiçbir fabrika bağlanmamış veya nextpdf/artisan mevcut değil.
Hız sınırı reddetmeleri düğümler arasında tutarsızBellek içi sınırlayıcı işlem başına çalışır; önüne paylaşılan bir depo yerleştirin.

Güvenlik açıklarını GitHub Security Advisories aracılığıyla veya depodaki SECURITY.md içinde belirtilen güvenlik iletişim noktası aracılığıyla bildirin. Güvenlik sorunlarını herkese açık GitHub sorunları olarak açmayın.

  • /integrations/cloudflare/overview/ — bu paketin neden sınır etrafında tasarlandığı.
  • /integrations/cloudflare/configuration/ — sabitleme kümesi ve sınır alanları.
  • /integrations/cloudflare/troubleshooting/ — başarısızlıkların özel durumlara tam eşlemesi.