Contracts / Kebijakan Keamanan
Sekilas pandang
Bagian berjudul “Sekilas pandang”Domain security-policy mendefinisikan tiga contract yang menolak secara default: CryptoPolicyInterface mengendalikan pilihan algoritme dan kunci, HtmlSecurityPolicyInterface membatasi permukaan fitur Hypertext Markup Language (HTML), dan ExternalResourcePolicyInterface mengatur pemuatan sumber daya jarak jauh. Karena semuanya berupa contract, Anda dapat menyediakan kebijakan deployment yang lebih ketat tanpa melakukan fork.
Pemasangan
Bagian berjudul “Pemasangan”composer require nextpdf/core:^3Tinjauan konseptual
Bagian berjudul “Tinjauan konseptual”CryptoPolicyInterface adalah gerbang kriptografi. Core memanggilnya sebelum setiap tahap penandatanganan, enkripsi, atau hashing. Pemeriksaan ini mencakup hash, object identifier (OID) tanda tangan, cipher, dan kekuatan kunci. Contract ini juga melaporkan hash minimum dan nama kebijakan untuk log audit. Gunakan contract ini untuk menerapkan kumpulan aturan seperti Federal Information Processing Standards (FIPS) 140-3 atau eIDAS. Kode penandatanganan dan enkripsi tetap tidak berubah. Jika tidak ada kebijakan yang ditetapkan, semua algoritme diizinkan. Situs yang teregulasi harus menetapkan kebijakan secara eksplisit.
HtmlSecurityPolicyInterface bekerja di lapisan parsing HTML. Interface ini berjalan sebelum konten mencapai renderer mana pun. Interface ini menentukan apakah suatu tag, atribut, properti Cascading Style Sheets (CSS), atau skema uniform resource locator (URL) diizinkan. Interface ini juga membatasi ukuran input dan kedalaman penyarangan. Interface ini bekerja sama dengan kebijakan transport per-renderer (Chrome, Cloudflare, Gotenberg), yang menetapkan batas ukuran dan header Content Security Policy (CSP). Kebijakan HTML mengurangi permukaan serangan di lapisan parsing. Tag yang sudah dihapus tidak pernah mencapai tata letak. Elemen yang disisipkan tidak dapat mengubah keluaran. Jika tidak ada kebijakan yang ditetapkan, pengaturan bawaan mengizinkan seluruh rangkaian fitur.
ExternalResourcePolicyInterface menentukan apakah pipeline HTML boleh mengambil fon, stylesheet, atau gambar eksternal. Interface ini juga menetapkan batas untuk setiap pengambilan. Postur bawaannya adalah menolak semua. Setiap opsi tetap nonaktif hingga Anda mengaktifkannya. Contract ini menganut prinsip hak istimewa paling sedikit. HTML yang tidak tepercaya dapat menunjuk ke URL yang dikendalikan penyerang. Interface ini mengendalikan pengambilan @font-face berdasarkan skema, ukuran, dan jumlah glif. Interface ini mengendalikan @import berdasarkan skema, kedalaman, dan ukuran total. Interface ini mengendalikan background-image berdasarkan daftar skema dan allowlist domain dengan pencocokan persis. Interface ini membatasi ukuran data-URI (Uniform Resource Identifier). Interface ini juga mengendalikan referensi eksternal Scalable Vector Graphics (SVG). Contract ini menyatakan bahwa lingkungan produksi harus selalu menolaknya. Referensi tersebut memungkinkan pemalsuan permintaan dan injeksi skrip. Pengambilan URL yang terbuka merupakan jalur server-side request forgery. Kontrol akses dilewati dengan mengubah URL, sebagaimana diuraikan oleh Open Worldwide Application Security Project (OWASP) Top 10 2025. Pengadaan komponen eksternal harus dibatasi pada sumber resmi dan transport yang aman.
Permukaan API
Bagian berjudul “Permukaan API”| Tipe | Jenis | Anggota utama | Stabilitas | Sejak |
|---|---|---|---|---|
CryptoPolicyInterface | interface | isHashAlgorithmAllowed(), isSignatureAlgorithmAllowed(), isEncryptionAlgorithmAllowed(), isKeyStrengthAllowed(), getPreferredHashAlgorithm(), getName() | stabil | 1.9.0 |
HtmlSecurityPolicyInterface | interface | isTagAllowed(), isAttributeAllowed(), isCssPropertyAllowed(), isUrlSchemeAllowed(), getMaxInputSize(), getMaxNestingDepth(), getName() | stabil | 3.1.0 |
ExternalResourcePolicyInterface | interface | isFontFaceAllowed(), getAllowedFontSchemes(), getMaxFontFileSize(), getMaxFontGlyphs(), isImportAllowed(), getMaxImportDepth(), isBackgroundImageAllowed(), getAllowedImageDomains(), getMaxDataUrlSize(), isSvgExternalReferenceAllowed() | stabil | 4.0.0 |
ExternalResourcePolicyInterface mengembalikan batas bertipe: ukuran positive-int, kedalaman import int<1, 100>, serta daftar skema dan domain list<non-empty-string>. Implementasi bawaan menolak setiap kapabilitas.
Contoh kode — Mulai cepat
Bagian berjudul “Contoh kode — Mulai cepat”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HtmlSecurityPolicyInterface;
/** * Decide whether a tag survives the policy. * * @param HtmlSecurityPolicyInterface $policy A core or custom policy. */function tagSurvives(HtmlSecurityPolicyInterface $policy, string $tag): bool{ return $policy->isTagAllowed($tag);}Fungsi ini hanya bergantung pada contract. Kebijakan yang restriktif maupun kebijakan bawaan sama-sama memenuhi contract tersebut.
Contoh kode — Produksi
Bagian berjudul “Contoh kode — Produksi”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\CryptoPolicyInterface;use NextPDF\Contracts\ExternalResourcePolicyInterface;use NextPDF\Contracts\HtmlSecurityPolicyInterface;use Psr\Log\LoggerInterface;
final readonly class UntrustedHtmlGate{ public function __construct( private HtmlSecurityPolicyInterface $htmlPolicy, private ExternalResourcePolicyInterface $resourcePolicy, private CryptoPolicyInterface $cryptoPolicy, private LoggerInterface $logger, ) {}
/** * Reject input that exceeds the configured limits before rendering. * * @param string $html Untrusted HTML markup. */ public function assertAcceptable(string $html): void { $maxInput = $this->htmlPolicy->getMaxInputSize();
if ($maxInput > 0 && \strlen($html) > $maxInput) { $this->logger->warning('HTML rejected: input over limit', [ 'policy' => $this->htmlPolicy->getName(), 'limit' => $maxInput, ]);
throw new \LengthException('HTML input exceeds policy limit.'); }
if ($this->resourcePolicy->isSvgExternalReferenceAllowed()) { $this->logger->error('Unsafe policy: SVG external references enabled.');
throw new \LogicException('SVG external references must be denied in production.'); } }}Gerbang ini menegakkan batas input dan menolak kebijakan sumber daya yang tidak aman sebelum pipeline berjalan. Gerbang ini mencatat nama kebijakan untuk audit dan melempar exception yang spesifik.
Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”CryptoPolicyInterfacemengizinkan setiap algoritme jika tidak ada kebijakan yang ditetapkan. Pengaturan bawaan yang terbuka adalah kemudahan untuk pengembangan, bukan postur produksi. Tetapkan kebijakan secara eksplisit pada setiap deployment yang teregulasi.HtmlSecurityPolicyInterface::getMaxInputSize()mengembalikan0untuk tanpa batas. Perlakukan0sebagai “tanpa batas dari kebijakan”, bukan “tolak semua”. Terapkan juga batas pada lapisan transport.ExternalResourcePolicyInterfacesecara default menolak semua. Mengaktifkan@font-faceataubackground-imagetanpa menetapkan daftar skema membuka permukaan serangan pemalsuan permintaan; tetapkan allowlist pada saat yang sama.- Allowlist domain yang kosong pada
getAllowedImageDomains()berarti semua domain diizinkan setelah gambar latar belakang diaktifkan. Daftar kosong bukan aturan penolakan; sediakan domain secara eksplisit. isSvgExternalReferenceAllowed()harus mengembalikanfalsedi lingkungan produksi. Contract mendokumentasikan hal ini; kebijakan yang mengembalikantrueadalah temuan, bukan pilihan konfigurasi.
Kinerja
Bagian berjudul “Kinerja”Pemeriksaan kebijakan berupa pemanggilan predikat: O(1), tanpa biaya yang sebanding dengan ukuran input. Kebijakan dirujuk per tag, per atribut, per properti CSS, dan per URL selama parsing. Dokumen patologis melipatgandakan jumlah pemanggilan, tetapi setiap pemanggilan tetap berjalan dalam waktu konstan. performance_budget sebesar 1500 ms wall dan puncak 64 MB didominasi oleh parsing dan rendering, bukan oleh evaluasi kebijakan. Batas ukuran input dan kedalaman penyarangan membatasi biaya parser itu sendiri. Kebijakan yang ketat meningkatkan kinerja kasus terburuk dengan menolak dokumen yang berukuran berlebih atau memiliki penyarangan dalam sebelum tata letak.
Catatan keamanan
Bagian berjudul “Catatan keamanan”Contract ini membentuk perimeter pertahanan engine, sehingga model ancamannya dibuat eksplisit. CryptoPolicyInterface memitigasi downgrade algoritme dengan memblokir hash yang lemah dan kunci yang pendek sebelum operasi apa pun. HtmlSecurityPolicyInterface memitigasi cross-site scripting yang memengaruhi keluaran Portable Document Format (PDF) dan injeksi konten dengan menghapus tag, atribut, dan CSS yang tidak diizinkan pada lapisan parsing sebelum renderer berjalan. ExternalResourcePolicyInterface memitigasi server-side request forgery, bom dekompresi, dan bom ukuran kumulatif dengan menolak semua secara default dan membatasi setiap pengambilan berdasarkan skema, ukuran, kedalaman, dan domain. Batas ukuran input, kedalaman penyarangan, glif fon, dan kedalaman import memitigasi penghabisan sumber daya. Karena setiap kebijakan merupakan contract, Anda dapat memperkuat perimeter tanpa melakukan fork pada engine, dan nama kebijakan diekspos untuk pencatatan audit. Perlakukan semua HTML, semua URL, serta semua byte fon dan gambar sebagai berbahaya. Halaman ini ditandai export_control_class: legal-review-required karena contract mengatur kebijakan kriptografi; teksnya memparafrasekan semua sumber normatif dan tidak mengutip satu pun.
Kesesuaian
Bagian berjudul “Kesesuaian”| Klaim | Standar | Klausa | Bukti |
|---|---|---|---|
| Penanganan URL yang tidak dibatasi memungkinkan perubahan URL melewati kontrol akses; kebijakan sumber daya eksternal memitigasinya melalui pengaturan bawaan yang menolak semua dan allowlist domain dengan pencocokan persis. | OWASP Top 10 2025 | A01 | |
| Pengadaan komponen eksternal harus dibatasi pada sumber resmi dan transport yang aman; kebijakan ini mendukungnya melalui allowlist skema. | OWASP Top 10 2025 | Rantai pasok perangkat lunak |
Kedua poin tersebut memparafrasekan panduan OWASP. Halaman ini merujuk materi OWASP berdasarkan klausa; engine tidak mereproduksi teksnya.
Konteks komersial
Bagian berjudul “Konteks komersial”Core mendefinisikan dan membekukan ketiga contract kebijakan tersebut. Core menyertakan pengaturan bawaan yang permisif untuk pengembangan serta pengaturan bawaan yang ketat untuk kebijakan sumber daya yang menolak semua. Edisi Enterprise menyertakan profil FIPS 140-3 di balik CryptoPolicyInterface, sehingga deployment yang teregulasi memperoleh postur algoritme yang tervalidasi tanpa mengubah kode penandatanganan atau enkripsi. Permukaan contract identik di seluruh edisi. Perbedaannya terletak pada implementasi kebijakan yang Anda suntikkan.
Lihat juga
Bagian berjudul “Lihat juga”- Contracts: 41 antarmuka publik (service provider interface, SPI) — tinjauan umum dan tingkatan stabilitas.
- Contracts / Signing —
CryptoPolicyInterfaceyang diterapkan pada penandatanganan. - Contracts / Document — titik masuk
writeHtml()danimage()yang dikendalikan oleh kebijakan ini. - Security — permukaan enkripsi yang dibatasi oleh kebijakan kripto.
- HTML — pipeline parsing yang dijaga oleh kebijakan HTML dan sumber daya.
- Audit — pencatatan audit nama kebijakan.