Keamanan dan operasional NextPDF Gotenberg
Sekilas
Bagian berjudul “Sekilas”Bridge ini mengirim dokumen dari aplikasi Anda ke layanan eksternal melalui jaringan. Karena itu, bridge menjadi permukaan permintaan sisi server sekaligus permukaan keamanan transport. Paket ini menerapkan kontrol khusus yang dapat diverifikasi untuk keduanya. Namun, paket ini tidak mengamankan seluruh sistem dengan sendirinya. Kontrol tersebut hanya efektif jika Anda menerapkan dan mengoperasikan Gotenberg dengan pengaman yang sesuai. Halaman ini menjelaskan kontrol yang diterapkan paket ini beserta tugas operasional yang melengkapinya.
Tidak ada hal di halaman ini yang merupakan jaminan. Setiap kontrol adalah perilaku yang terdefinisi, tercakup oleh pengujian, dan memiliki batasan yang dinyatakan secara eksplisit.
Dua lapisan kebijakan
Bagian berjudul “Dua lapisan kebijakan”Bridge menerapkan dua kebijakan keamanan yang berbeda pada lapisan yang berbeda:
- Kebijakan transport (
GotenbergSecurityPolicy) — penegakan skema URL, penyaringan server-side request forgery (SSRF), pertahanan terhadap rebinding Domain Name System (DNS), batas ukuran masukan, dan penyaringan nama berkas. Inilah lapisan yang didokumentasikan secara mendalam di bawah ini. - Kebijakan parse HTML — kebijakan konten pada lapisan parse, yang secara baku menggunakan kebijakan standar inti NextPDF, dan berjalan sebelum konten mencapai renderer. Kebijakan ini melengkapi kebijakan transport tetapi tetap independen darinya. Halaman ini membahas kebijakan transport.
Penyaringan server-side request forgery (SSRF)
Bagian berjudul “Penyaringan server-side request forgery (SSRF)”Bridge menyaring URL API yang dikonfigurasikan sebelum satu byte pun keluar dari proses. Kontrol ini terdiri dari tiga bagian.
Penegakan skema. Hanya https yang diterima (tidak peka huruf besar-kecil). URL http:// biasa ditolak. Karena itu, Transport Layer Security (TLS) wajib untuk setiap konversi dan probe kesehatan.
Penyaringan alamat. Jika host berupa literal IP, bridge menolaknya bila berada dalam rentang privat atau terreservasi. Jika host berupa nama, bridge melakukan resolve ke semua record A dan AAAA miliknya, lalu menolak permintaan jika ada alamat hasil resolve yang bersifat privat atau terreservasi. Melakukan resolve atas seluruh kumpulan record, bukan hanya satu alamat, adalah kontrol yang menggagalkan penyerang yang menyembunyikan alamat privat di balik nama yang juga mengembalikan alamat publik. Ini mengikuti pendekatan panduan pencegahan SSRF dari OWASP: ambil setiap alamat IP di balik nama domain (record A dan AAAA, untuk IPv4 dan IPv6), dan validasi masing-masing terhadap allowlist (OWASP Cheat Sheet Series, pencegahan SSRF, pertahanan lapisan aplikasi; disematkan dalam sidecar retrieval-augmented generation (RAG) halaman ini).
Pemeriksaan ulang time-of-check/time-of-use (TOCTOU). Tepat sebelum permintaan dikirim, bridge melakukan resolve ulang dan membandingkannya dengan kumpulan alamat yang dicatat saat validasi. Jika muncul alamat baru, permintaan dibatalkan dengan galat DNS-rebinding. Hal ini menutup celah antara validasi dan koneksi yang semestinya dieksploitasi oleh serangan rebinding.
Ketika bridge menggunakan transport cURL yang di-pin, kumpulan alamat yang telah divalidasi diikat ke koneksi dengan CURLOPT_RESOLVE, sehingga kernel terhubung ke alamat yang telah ditelaah, bukan ke apa pun yang mungkin dikembalikan oleh pencarian DNS baru pada waktu koneksi. Pengikutan pengalihan dinonaktifkan pada transport tersebut (CURLOPT_FOLLOWLOCATION nonaktif, CURLOPT_MAXREDIRS nol), sehingga sebuah 3xx tidak dapat secara diam-diam mengirim permintaan ke host yang belum ditelaah. Sebagai gantinya, lapisan kebijakan menerima respons tersebut.
Konsekuensi operasional. Kontrol SSRF menolak alamat privat dan terreservasi secara sengaja. Jika Gotenberg Anda berjalan di jaringan privat, Anda tidak dapat mengarahkan bridge ke alamat privatnya. Ekspos melalui alamat yang diterima kontrol tersebut dan lindungi jalur itu dengan segmentasi jaringan serta autentikasi, sebagaimana dijelaskan pada bagian penerapan di bawah ini.
Keamanan transport dan pinning kunci publik
Bagian berjudul “Keamanan transport dan pinning kunci publik”Verifikasi peer dan host TLS selalu aktif pada transport cURL yang di-pin (CURLOPT_SSL_VERIFYPEER true, CURLOPT_SSL_VERIFYHOST 2). Selain validasi rantai standar, bridge mendukung pinning SubjectPublicKeyInfo (SPKI).
Setiap pin adalah hash SHA-256 dari SubjectPublicKeyInfo server, yang dinyatakan sebagai sha256/<base64>. Bridge menerima sertifikat ketika hash SPKI-nya cocok dengan pin mana pun dalam gabungan kumpulan pin primer dan cadangan. Model pin cadangan ini mengikuti RFC 7469 §4.3, yang mengidentifikasi pin cadangan — sidik jari dari pasangan kunci sekunder yang belum diterapkan — sebagai jalur pemulihan utama untuk kegagalan validasi pin yang tidak disengaja, serta §2.5, yang mensyaratkan kumpulan pin menyertakan setidaknya satu pin yang tidak ada dalam rantai sertifikat saat ini (RFC 7469 §4.3 dan §2.5; disematkan dalam sidecar RAG halaman ini). Kode bridge mendeklarasikan RFC 7469 §2.1 dan §2.6 untuk semantik setidaknya-satu-pin-cadangan dan irisan kumpulan gabungan. Pinning bersifat opt-in: tanpa pin yang dikonfigurasikan, validasi rantai standar berlaku dan pinning tidak ditegakkan.
Pin yang tidak dapat di-parse memunculkan galat konfigurasi sebelum permintaan apa pun. Sertifikat aktif yang SPKI-nya tidak cocok dengan pin yang dikonfigurasikan akan membuat transport menggagalkan permintaan — secara sengaja.
Prosedur rotasi pin
Bagian berjudul “Prosedur rotasi pin”Rotasi yang salah membuat bridge kehilangan akses ke layanan. Lakukan rotasi tanpa gangguan layanan:
- Sebelum mengubah kunci server, buat pin SPKI untuk kunci baru dan tambahkan ke daftar pin cadangan. Terapkan konfigurasi tersebut. Bridge kini menerima kunci saat ini maupun kunci mendatang.
- Lakukan pergantian sertifikat atau kunci server agar menggunakan kunci baru.
- Pastikan konversi masih berhasil (kunci baru kini cocok dengan pin cadangan).
- Pindahkan pin baru dari daftar cadangan ke daftar primer dan hapus pin kunci yang telah dipensiunkan. Terapkan.
- Buat dan siapkan pin untuk rotasi berikutnya sebagai cadangan baru sehingga kumpulan pin selalu membawa cadangan yang dapat digunakan.
Dengan menjaga daftar cadangan tetap terpisah dari daftar primer, Anda dapat menyiapkan dan memvalidasi pin berikutnya tanpa menyentuh pin yang aktif.
Autentikasi
Bagian berjudul “Autentikasi”Ketika apiKey tidak kosong, bridge mengirimkannya sebagai header Authorization: Bearer pada permintaan konversi. Field ini ditandai #[\SensitiveParameter] sehingga nilainya disamarkan di stack trace. Bridge tidak memuat secret untuk Anda; pasok dari secret manager saat proses dimulai dan jangan pernah meng-commit-nya. Token tidak ditulis ke log permintaan — entri debug yang dicatat hanya berisi URL, nama berkas, format, dan panjang konten.
Batas kepercayaan respons
Bagian berjudul “Batas kepercayaan respons”Respons hanya diterima ketika statusnya 200, Content-Type mengandung application/pdf, dan body diawali dengan penanda %PDF. Pemeriksaan penanda byte penting karena tipe konten yang dideklarasikan saja tidak membuktikan apa sebenarnya byte tersebut. Standar WHATWG MIME Sniffing memformalkan penalaran yang sama dalam algoritme sniffing tipe MIME-nya, yang menurunkan tipe terhitung dari pencocokan pola byte awal, bukan dari tipe yang dipasok. Panduan unggah berkas OWASP menyatakan prinsip aplikasi yang selaras: validasi tipe berkas dan jangan percaya header Content-Type yang dideklarasikan, karena dapat dipalsukan (WHATWG MIME Sniffing §6.2.3; OWASP Cheat Sheet Series, validasi unggah berkas; keduanya disematkan dalam sidecar RAG halaman ini). Bridge menerapkan pemeriksaan defensif yang setara pada sisi masuk: ketidakcocokan memunculkan exception bertipe, dan byte tidak pernah dikembalikan sebagai hasil.
Batas ini juga menjadi alasan mengapa kontrak PSR-18 penting di sini. Klien PSR-18 hanya melempar exception ketika tidak dapat mengirim permintaan atau tidak dapat mem-parse respons menjadi objek PSR-7 — klien tidak melempar exception pada kode status galat. Respons 4xx/5xx yang terbentuk dengan baik dikembalikan ke pemanggil seperti biasa (PSR-18, “Exceptions”; disematkan dalam sidecar RAG halaman ini). Karena itu, bridge sendiri yang memeriksa status, tipe, dan penanda, alih-alih mengasumsikan bahwa respons yang dikembalikan berhasil. Semantik HTTP untuk pelanggaran batasan content-type — penolakan 415 (Unsupported Media Type), ketika server menolak konten dalam format yang tidak didukung — adalah model yang dicerminkan oleh pemeriksaan masuk (RFC 9110 §15.5.16; disematkan dalam sidecar RAG halaman ini).
Batas sumber daya
Bagian berjudul “Batas sumber daya”Bridge memiliki satu batas sumber daya dalam proses: maxFileSize (baku 52,428,800 bytes = 50 MiB). Batas ini ditegakkan sebelum permintaan dikirim, sehingga masukan yang terlalu besar tidak pernah mencapai layanan. Tidak ada batas konkurensi, batas laju, atau batas ukuran keluaran bawaan dalam bridge. Hal-hal tersebut merupakan tanggung jawab penerapan dan pemanggil (lihat /integrations/gotenberg/production-usage/). Atur maxFileSize ke nilai terkecil yang dibutuhkan dokumen nyata Anda — batas yang lebih ketat adalah kontrol denial-of-service yang lebih murah.
Menerapkan dan mengamankan layanan Gotenberg
Bagian berjudul “Menerapkan dan mengamankan layanan Gotenberg”Bridge hanya seaman layanan yang dipanggilnya. Anda yang mengoperasikan layanan tersebut; tugas-tugas di bawah ini melengkapi kontrol di atas.
- Terminasikan TLS di depan Gotenberg. Kontainer Gotenberg secara baku menggunakan HTTP biasa. Bridge mewajibkan HTTPS, jadi tempatkan Gotenberg di belakang reverse proxy, ingress, atau service mesh yang melakukan terminasi TLS, lalu arahkan bridge ke endpoint HTTPS. Pin SPKI proxy jika Anda mengaktifkan pinning.
- Jangan paparkan Gotenberg secara publik. Gotenberg melakukan konversi dokumen dengan mesin sekelas LibreOffice dan Chromium, dan bukan layanan yang menghadap internet. Batasi ingress hanya ke host aplikasi yang memanggilnya, menggunakan kebijakan jaringan atau aturan firewall.
- Wajibkan autentikasi pada jalur tersebut. Bridge mengirimkan bearer token bila dikonfigurasikan; tegakkan token tersebut (atau mutual TLS) pada proxy sehingga permintaan yang tidak terautentikasi tidak dapat mencapai mesin konversi.
- Pin versi layanan yang spesifik. Bridge mengasumsikan tepat dua jalur layanan —
/forms/libreoffice/convertdan/health. Pin image Gotenberg ke tag patch yang spesifik, verifikasi kedua jalur tersebut terhadap versi yang Anda terapkan, dan verifikasi ulang pada setiap peningkatan versi. - Tentukan kapasitas konversi secara cermat. Setiap konversi menahan satu worker selama durasi permintaan. Rancang ukuran penerapan Gotenberg untuk laju konversi serentak puncak Anda dan batasi konversi yang sedang berlangsung di sisi pemanggil agar sesuai. Kapasitas adalah properti penerapan Anda, bukan paket ini.
- Perlakukan masukan konversi sebagai tidak tepercaya. Dokumen yang dilewatkan melalui konversi diproses oleh mesin yang rumit. Batasi
maxFileSize, isolasi penerapan Gotenberg (segmen jaringan tersendiri, egress minimal, tanpa akses ke layanan internal), dan pastikan mesin tetap mendapatkan patch.
Apa yang tidak diklaim paket ini
Bagian berjudul “Apa yang tidak diklaim paket ini”- Paket ini bukan “aman secara baku”: kontrolnya nyata tetapi bergantung pada penerapan dan konfigurasi yang benar.
- Paket ini tidak menjadikan konversi “anti-rusak” atau keluaran “tersertifikasi”. Paket ini memvalidasi transport dan bentuk respons; paket ini tidak memberikan atestasi atas isi dokumen.
- Paket ini tidak menyediakan penandatanganan, pembubuhan stempel waktu, atau validasi jangka panjang. Hal-hal itu merupakan urusan pascapemrosesan. Dukungan PAdES edisi Pro hanya baseline B-B dan tidak mencakup B-T, B-LT, atau B-LTA; tidak ada hal dalam bridge ini yang menyiratkan kemampuan stempel waktu atau LTV.
- Paket ini tidak mendukung “semua berkas Office”. Paket ini mendukung enam format yang disebutkan dan menolak semua yang lain sebelum permintaan apa pun.
Lihat juga
Bagian berjudul “Lihat juga”- /integrations/gotenberg/configuration/ — aturan pemilihan transport dan model pin yang lengkap.
- /integrations/gotenberg/production-usage/ — percobaan ulang, batas waktu, konkurensi, dan observabilitas.
- /integrations/gotenberg/troubleshooting/ — setiap exception keamanan dan pemicunya.
- /integrations/gotenberg/overview/ — alur konversi dan model dependensi.