💡 Contoh kerja penuh tersedia di GitHub:
skip-external-resources-when-signing-dotnet

Pendahuluan

Dokumen Word dapat berisi gambar yang tidak berada dalam berkas. Dokumen menyimpan sebuah alamat, dan apa pun yang membukanya akan mengambil alamat tersebut. Pada desktop ini adalah sebuah fitur – gambar akan diperbarui ketika sumbernya berubah. Pada server yang menerima unggahan, ini berarti orang yang mengirimkan berkas kepada Anda menentukan URL mana yang diminta infrastruktur Anda.

Pemuat dokumen yang aman adalah perilaku GroupDocs.Signature untuk .NET yang menolak melakukan permintaan tersebut. Mulai versi 26.9, LoadOptions.SkipExternalResources secara bawaan bernilai true. Artikel ini membandingkan tiga mode pemuatan terhadap dokumen yang sama, menunjukkan cara mengizinkan satu host tanpa mengizinkan semuanya, dan menjelaskan mengapa penandatanganan berkas yang tidak dipercaya tidak memerlukan akses jaringan sama sekali.

Mengapa Ini Lebih Penting Dari yang Terdengar

Serangan ini memiliki nama – server‑side request forgery (SSRF) – dan tiga bentuk konkret.

Sebuah alamat internal yang tidak dapat dijangkau dari internet dapat dijangkau dari server Anda, sehingga dokumen yang dirancang dapat membuat layanan Anda mengambil http://169.254.169.254/ atau endpoint admin di localhost dan, tergantung apa yang Anda lakukan dengan hasilnya, membocorkannya. Jalur UNC dalam dokumen dapat memaksa host Windows untuk melakukan otentikasi keluar, menyerahkan kredensial ke server yang dikendalikan penyerang. Dan tautan ke host yang tidak pernah menjawab akan menahan thread pemuatan hingga waktu habis, yang merupakan cara murah untuk menguras kumpulan pekerja.

Saya mengira ini hanya masalah teoretis sampai saya melihat dokumen uji menarik gambar melalui layanan yang tidak seharusnya membuat permintaan keluar sama sekali. Tidak ada yang memerlukan bug dalam pustaka dokumen. Mengikuti tautan adalah apa yang diminta format; pertanyaannya hanyalah apakah server Anda harus mematuhinya.

Metode 1 - Default Baru

Tanpa LoadOptions sama sekali:

using var signature = new Signature(sourcePath);
return SavePagePreview(signature, previewPath);

Tidak ada yang diambil. Pratinjau menampilkan placeholder kosong di tempat gambar yang ditautkan seharusnya, dan PNG yang dihasilkan lebih kecil daripada bila gambar diambil. Perbedaan ukuran itulah bukti paling praktis bahwa tidak ada permintaan yang keluar dari mesin.

Fitur apa yang dihitung sebagai eksternal? Gambar yang ditautkan daripada yang disematkan, bidang INCLUDEPICTURE, gambar yang ditautkan dalam presentasi dan spreadsheet, serta gambar dan lembar gaya yang direferensikan oleh SVG. Konten yang disematkan tidak tersentuh – sudah berada dalam berkas.

Metode 2 - Daftar Putih Satu Alamat

Banyak dokumen menautkan ke sesuatu yang sah: CDN perusahaan, server gambar internal, toko templat. Izinkan itu dan tidak ada yang lain:

var loadOptions = new LoadOptions
{
    WhitelistedResources = new List<string> { trustedAddress }
};

using var signature = new Signature(sourcePath, loadOptions);

Aturan pencocokan memerlukan perhatian. Ini adalah tes substring yang tidak sensitif huruf besar/kecil terhadap alamat sumber daya, yang berarti fragmen pendek berbahaya: github cocok dengan github.attacker.example/payload.png sama mudahnya dengan host yang Anda maksud. Gunakan skema, host, dan jalur – contoh daftar putih raw.githubusercontent.com/groupdocs-signature/.

Metode 3 - Izinkan Semua

Perilaku sebelum versi 26.9, masih tersedia:

var loadOptions = new LoadOptions { SkipExternalResources = false };

Masuk akal untuk dokumen yang dihasilkan oleh aplikasi Anda sendiri. Satu jebakan yang patut dicatat: properti usang LoadExternalResources memiliki polaritas berlawanan, sehingga SkipExternalResources = false menggantikan LoadExternalResources = true. Menyalin nilai dari properti lama akan membalikkan postur keamanan Anda tanpa ada kesalahan yang memberi tahu.

Membandingkan Ketiganya: Kapan Menggunakan Masing‑Masing

Mode Terbaik Untuk Keunggulan Utama Keterbatasan
Default (skip) unggahan pengguna, email, berkas mitra tidak ada permintaan keluar yang mungkin gambar yang ditautkan muncul sebagai placeholder
Daftar Putih dokumen yang menautkan ke host milik Anda menjaga tautan sah tetap berfungsi pencocokan substring memerlukan fragmen yang panjang dan spesifik
Izinkan Semua berkas yang dihasilkan sistem Anda pratinjau terlihat persis seperti sebelumnya mengembalikan risiko SSRF yang dihilangkan oleh default

Bagaimana dengan penandatanganan - apakah itu membutuhkan sumber daya?

Tidak, dan inilah manfaat praktisnya. Tanda QR‑code diterapkan dengan pengaturan pemuatan default dan tidak ada sumber daya eksternal yang diminta saat dokumen dimuat, ditandatangani, atau disimpan:

var options = new QrCodeSignOptions("Approved by GroupDocs.Signature")
{
    EncodeType = QrCodeTypes.QR,
    Left = 400,
    Top = 50,
    Width = 120,
    Height = 120
};

SignResult result = signature.Sign(outputPath, options);

Output yang ditandatangani tetap menyimpan tautannya, sehingga pengguna yang membuka dokumen nanti masih melihat gambar yang diambil di mesin mereka sendiri. Melewatkan permintaan adalah kebijakan sisi server, bukan pengeditan pada dokumen – itulah yang membuatnya aman untuk diterapkan pada berkas yang Anda tangani atas nama orang lain.

Apa yang Berubah Saat Anda Memperbarui

Untuk kebanyakan layanan, tidak ada yang terlihat pada pandangan pertama, dan itu penting untuk dinyatakan secara jelas karena perubahan default keamanan yang memengaruhi perilaku di mana pun tidak akan lolos tinjauan pembaruan. Pengecualian terjadi di mana pratinjau atau thumbnail sebelumnya menampilkan gambar yang ditautkan dan kini menampilkan placeholder; itulah perubahan yang melakukan tugasnya, dan solusinya adalah menambahkan entri daftar putih jika host tersebut milik Anda, atau menerima jika dokumen berasal dari luar.

Cara jujur untuk memeriksanya adalah yang digunakan contoh: render dokumen yang sama dalam ketiga mode dan bandingkan ukuran output. Jika pratinjau default dan yang berada dalam daftar putih memiliki ukuran yang identik, tidak ada yang diambil dalam kedua kasus – yang biasanya berarti host tidak dapat dijangkau dari mesin tersebut, bukan bahwa daftar putih gagal, dan contoh mencetak petunjuk yang menyatakan hal itu.

Penolong Pratinjau, Karena Tidak Jelas

Dua dari tiga mode di atas memanggil sebuah pembantu kecil, dan layak ditampilkan karena PreviewOptions tidak menerima jalur:

var previewOptions = new PreviewOptions(
    pageData => File.Create(previewPath),
    (pageData, pageStream) => pageStream.Dispose())
{
    PreviewFormat = PreviewOptions.PreviewFormats.PNG
};

signature.GeneratePreview(previewOptions);

Ia menerima dua pabrik aliran – satu untuk membuat aliran per halaman, satu untuk melepaskannya. Dokumen contoh memiliki satu halaman, sehingga satu berkas ditulis; untuk masukan multi‑halaman, letakkan nomor halaman dalam nama berkas atau setiap halaman akan menimpa yang sebelumnya.

Praktik Terbaik

  • Anggap segala sesuatu yang tidak Anda hasilkan sebagai tidak terpercaya, termasuk berkas dari mitra yang memiliki postur keamanan baik.
  • Buat fragmen daftar putih cukup panjang agar tidak ambigu, dan tinjau kembali ketika CDN berubah.
  • Jangan pernah mengatur SkipExternalResources dari nilai yang sebelumnya diberikan ke LoadExternalResources.
  • Verifikasi dengan ukuran output daripada dengan pengaturan; konfigurasi yang tampak benar dan permintaan yang tidak terjadi adalah klaim yang berbeda.

Di Mana Ini Meninggalkan SVG

Patut disebutkan secara terpisah, karena SVG merupakan format unggahan yang umum dan vektor SSRF yang umum. SVG dapat mereferensikan gambar dan lembar gaya melalui URL, dan referensi tersebut adalah sumber daya eksternal di bawah aturan yang sama – dilewati secara default, dapat dimasukkan ke daftar putih, dapat dipulihkan. Layanan yang menerima avatar atau logo SVG dan merendernya di sisi server adalah contoh tepat dari sistem yang dilindungi oleh perubahan ini.

Jika alur kerja Anda menerima SVG dari pengguna, default adalah pengaturan yang Anda inginkan, dan daftar putih berguna untuk kasus di mana templat Anda sendiri mengambil lembar gaya bersama dari host yang Anda kelola.

Kesimpulan

Default telah dibalik sehingga perilaku berisiko memerlukan keputusan eksplisit dan yang aman tidak memerlukan apa‑apa. Pertahankan default untuk masukan yang tidak terpercaya, gunakan daftar putih secara sempit bila host Anda terlibat, dan ingat bahwa penandatanganan itu sendiri tidak pernah memerlukan jaringan. Menjalankan contoh terhadap salah satu dokumen Anda sendiri memakan waktu satu menit dan memberi tahu Anda, dalam tiga ukuran berkas, tepat apa yang telah diambil layanan Anda.

Sumber Daya Tambahan