💡 Tam çalışan örnek GitHub’da mevcuttur:
skip-external-resources-when-signing-dotnet
Giriş
Bir Word belgesi, dosyada bulunmayan bir resim içerebilir. Belge bir adres tutar ve onu açan her şey bu adresi alır. Masaüstünde bu bir özelliktir – kaynak güncellendiğinde resim de güncellenir. Yüklemeleri kabul eden bir sunucuda ise, dosyayı gönderen kişi, altyapınızın hangi URL’leri isteyeceğini belirler.
Güvenli belge yükleme, .NET için GroupDocs.Signature davranışı olup bu istekleri reddeder. 26.9 sürümünden itibaren LoadOptions.SkipExternalResources varsayılan olarak true olur. Bu makale aynı belgeye karşı üç yükleme modunu karşılaştırır, tüm hostları izin vermeden tek bir hosta izin vermenin yolunu gösterir ve güvenilmeyen bir dosyanın imzalanmasının neden hiç ağ erişimine ihtiyaç duymadığını açıklar.
Neden Bu Göründüğünden Daha Önemli
Bu saldırının bir adı var – sunucu tarafı istek sahteciliği (SSRF) – ve üç somut şekli.
İnternetten erişilemeyen bir iç adres, sunucunuzdan erişilebilir olduğundan, hazırlanmış bir belge hizmetinizin http://169.254.169.254/ ya da localhost üzerindeki bir yönetici uç noktasını almasını sağlayabilir ve sonucun ne yapılacağına bağlı olarak bunu sızdırabilir. Bir belgede UNC yolu, bir Windows hostunun dışa kimlik doğrulaması yapmasını tetikleyebilir ve kimlik bilgilerini saldırgan kontrolündeki bir sunucuya teslim edebilir. Ayrıca, yanıt vermeyen bir hosta yönlendiren bir bağlantı, yükleme iş parçacığını zaman aşımına kadar meşgul tutar; bu da çalışan havuzunu tüketmenin ucuz bir yoludur.
Bunun sadece teorik bir endişe olduğunu varsaydım, ta ki bir test belgesinin hiç dış istek yapması gerekmeyen bir hizmet üzerinden bir resim çektiğini izleyene kadar. Bunun hiçbiri belge kütüphanesinde bir hata gerektirmez. Bir bağlantıyı takip etmek formatın istediği şeydir; soru sadece sunucunuzun buna uyması gerekip gerekmediğidir.
Yöntem 1 - Yeni Varsayılan
Hiç LoadOptions yok:
using var signature = new Signature(sourcePath);
return SavePagePreview(signature, previewPath);
Hiçbir şey alınmaz. Ön izleme, bağlantılı resmin bulunacağı yerde boş bir yer tutucu gösterir ve PNG, aksi takdirde olacağından daha küçüktür. Bu boyut farkı, makineden hiçbir isteğin çıkmadığını gösteren en pratik kanıttır.
Hangi özellikler dış olarak sayılır? Gömülü olmayan, bağlantılı resimler, INCLUDEPICTURE alanları, sunum ve elektronik tablolardaki bağlantılı resimler ve bir SVG’nin referans verdiği görüntüler ve stil sayfaları. Gömülü içerik dokunulmazdır – zaten dosyada bulunur.
Yöntem 2 - Tek Adresi Beyaz Listeye Al
Birçok belge meşru bir yere bağlanır: bir şirket CDN’i, dahili bir resim sunucusu, bir şablon deposu. Bunu izin ver, başka bir şey vermeyin:
var loadOptions = new LoadOptions
{
WhitelistedResources = new List<string> { trustedAddress }
};
using var signature = new Signature(sourcePath, loadOptions);
Eşleşme kuralı dikkat çekmelidir. Kaynak adresine karşı büyük/küçük harfe duyarsız bir alt dize testi yapılır; bu da kısa bir parçanın tehlikeli olduğu anlamına gelir: github, github.attacker.example/payload.png adresini, amaçladığınız host kadar eşleşir. Bir şema, bir host ve bir yol kullanın – örnek raw.githubusercontent.com/groupdocs-signature/ adresini beyaz listeye alır.
Yöntem 3 - Her Şeyi İzin Ver
26.9 öncesi davranış, hâlâ mevcut:
var loadOptions = new LoadOptions { SkipExternalResources = false };
Kendi uygulamanızın ürettiği belgeler için makul. Dikkat çekmeye değer bir tuzak: eski LoadExternalResources özelliği ters kutuplu olduğundan, SkipExternalResources = false ifadesi LoadExternalResources = true yerine geçer. Eski özelliğinden bir değeri kopyalarsanız, hiçbir hata mesajı almadan güvenlik duruşunuzu tersine çevirirsiniz.
Üçünü Karşılaştırma: Hangi Durumda Hangi Kullanılır
| Mod | En Uygun Kullanım | Ana Avantajlar | Sınırlamalar |
|---|---|---|---|
| Varsayılan (atla) | kullanıcı yüklemeleri, e-posta, ortak dosyalar | dış istek mümkün değildir | bağlantılı resimler yer tutucu olarak gösterilir |
| Beyaz Liste | sahibi olduğunuz bir hosta bağlanan belgeler | meşru bağlantıların çalışmasını sürdürür | alt dize eşleşmesi uzun, belirli bir parçaya ihtiyaç duyar |
| Hepsine İzin Ver | kendi sistemlerinizin ürettiği dosyalar | ön izlemeler önceki gibi görünür | varsayılanın kaldırdığı SSRF açığının geri getirilmesi |
İmzalama ile ilgili ne? - Kaynaklara ihtiyaç var mı?
Hayır ve bu pratik kazançtır. QR kodlu bir imza, varsayılan yükleme ayarlarıyla uygulanır ve belge yüklenirken, imzalanırken veya kaydedilirken hiçbir dış kaynak istenmez:
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);
İmzalı çıktı bağlantısını korur, böylece belgeyi daha sonra açan bir kullanıcı resmi kendi makinesinde çözülmüş olarak görür. Atlamak, belgeye bir düzenleme değil, sunucu tarafı bir politikadır – bu da başkasının adına işlediğiniz dosyalara güvenle uygulanmasını sağlar.
Yükseltildiğinde Ne Değişir
Çoğu hizmet için ilk bakışta görünür bir şey yoktur ve bu açıkça belirtilmeye değerdir çünkü davranışı her yerde değiştiren bir güvenlik varsayılanı yükseltme incelemesinden geçemez. İstisna, ön izleme veya küçük resmin daha önce bağlantılı bir resmi gösterdiği ve şimdi yer tutucu gösterdiği yerlerdir; bu değişiklik görevini yapıyor demektir ve çözüm, host sizinse bir beyaz liste girişi, dışarıdan geldiyse kabul etmektir.
Doğru kontrol yöntemi, örneğin kullandığı yöntemdir: aynı belgeyi üç modda da renderleyin ve çıktı boyutlarını karşılaştırın. Varsayılan ve beyaz listedeki ön izlemeler aynı boyutta ise, hiçbir durumda bir şey alınmamıştır – bu genellikle hostun o makineden erişilemez olduğu anlamına gelir, beyaz listenin başarısız olduğu değil, ve örnek tam olarak bunu söyleyen bir ipucu yazdırır.
Ön İzleme Yardımcısı, Açık Olmadığı İçin
Yukarıdaki üç moddan ikisi küçük bir yardımcıyı çağırır ve PreviewOptions bir yol almadığı için göstermek değerlidir:
var previewOptions = new PreviewOptions(
pageData => File.Create(previewPath),
(pageData, pageStream) => pageStream.Dispose())
{
PreviewFormat = PreviewOptions.PreviewFormats.PNG
};
signature.GeneratePreview(previewOptions);
İki akış fabrikası alır – sayfa başına bir akış oluşturmak için bir tane, onu serbest bırakmak için bir tane. Örnek belge tek sayfalıdır, bu yüzden bir dosya yazılır; çok sayfalı giriş için dosya adına sayfa numarasını ekleyin, aksi takdirde her sayfa sonrakini üzerine yazar.
En İyi Uygulamalar
- Ürettiğiniz hiçbir şeyi, iyi güvenlik duruşuna sahip ortaklardan gelen dosyalar dahil, güvensiz olarak değerlendirin.
- Beyaz liste parçacıklarını belirsiz olmayacak kadar uzun yapın ve bir CDN değiştiğinde gözden geçirin.
SkipExternalResourcesdeğerini, daha önceLoadExternalResources‘a atanmış bir değerden asla ayarlamayın.- Çıktı boyutlarıyla doğrulayın, ayarla değil; doğru görünen bir yapılandırma ve gerçekleşmeyen bir istek farklı iddialardır.
SVG’ye Ne Olur
Özel olarak belirtmeye değer, çünkü SVG hem yaygın bir yükleme formatı hem de yaygın bir SSRF vektörüdür. Bir SVG, URL ile görüntü ve stil sayfalarına referans verebilir ve bu referanslar aynı kural altında dış kaynaklardır – varsayılan olarak atlanır, beyaz listeye alınabilir, geri getirilebilir. SVG avatarları veya logoları kabul edip sunucu tarafında render eden bir hizmet, tam da bu değişikliğin koruduğu sistem şeklidir.
Kullanıcıların SVG kabul eden bir işlem hattınız varsa, varsayılan istediğiniz ayardır ve beyaz liste, kendi şablonlarınızın çalıştırdığınız bir hosttan paylaşılan bir stil sayfası çektiği durumlar içindir.
Sonuç
Varsayılan değiştirildi, böylece riskli davranış açık bir karar gerektirirken güvenli davranış hiçbir şeye ihtiyaç duymaz. Güvensiz giriş için varsayılanı koruyun, kendi hostlarınızın dahil olduğu durumlarda dar bir beyaz liste uygulayın ve imzalamanın kendisinin hiç ağa ihtiyaç duymadığını unutmayın. Örneği kendi belgelerinizden biriyle çalıştırmak bir dakikadan az sürer ve üç dosya boyutunda hizmetinizin neyi çektiğini tam olarak gösterir.