Sunucu
Sunucuda temizleme
Gönderilen HTML'i Node için @viveeditor/sanitize, PHP 8.4+ için viveeditor/sanitizer ile kaydederken ve gösterirken temizleyin.
Editör yalnızca bilinen bir HTML kümesi üretir, ama herkes sunucunuza istediği HTML’i gönderebilir. Bu yüzden içeriği saklamadan ya da göstermeden önce sunucuda temizleyin. Node için @viveeditor/sanitize ve PHP 8.4+ için viveeditor/sanitizer, editörün ürettiğini olduğu gibi tutar ve geri kalan her şeyi atar. İkisi tek bir izin listesini ve tek bir test derlemini paylaşır, aynı çıktıyı verir.
Kurulum
Node.js 20.19 ya da daha yeni sürüm için:
npm install @viveeditor/sanitize
PHP 8.4 ya da daha yeni sürüm için; dom ve mbstring eklentileri dışında bağımlılığı yoktur:
composer require viveeditor/sanitizer
Laravel kullanıyorsanız PHP temizleyicisini de getiren viveeditor/laravel paketini kullanın.
HTML’i temizleme
import { sanitizeHtml } from '@viveeditor/sanitize'
const clean = sanitizeHtml(request.body.html, { embeds: true })
use Viveeditor\Sanitizer\Sanitizer;
$clean = Sanitizer::sanitize($html, ['embeds' => true]);
Her öğe ve öznitelik tam bir HTML5 ayrıştırıcısıyla (Node’da parse5, PHP’de Dom\HTMLDocument) yeniden kurulur; böylece çıktı her tarayıcıda aynı okunur. İki kez temizlemek aynı sonucu verir.
Seçenekler
| Seçenek | Varsayılan | Etkisi |
|---|---|---|
embeds |
false |
Video ve ses yerleştirmelerini tutar. Oynatıcılar kopyalanmaz, sağlayıcı ve kimlikten yeniden kurulur. |
allowBase64 |
false |
data: adresi olarak saklanan görsellere (PNG, JPEG, GIF, WebP, AVIF) izin verir. |
allowRelativeImages |
false |
Göreli görsel adreslerine izin verir. |
maxBytes |
2 MB | Bundan büyük HTML TOO_LARGE hatası fırlatır. |
allowRelativeImages’ı yalnızca gerçekten gerekiyorsa açın: göreli bir görsel adresi, her okurun tarayıcısının kendi sitenize bir GET isteği göndermesine yol açar; bir yazar bunu bir şeyi değiştiren bir adrese yöneltebilir.
Hatalar
Temizleyici HTML’i hiçbir zaman yarıda kesmez. Girdiyi temizleyemediğinde hata fırlatır:
| Kod | Ne zaman |
|---|---|
TOO_LARGE |
HTML, maxBytes değerinden büyük. |
TOO_COMPLEX |
Yapı, ayrıştırıcıyı yavaşlatacak ya da çok bellek harcatacak türden: bir etikette 64’ten fazla öznitelik, 512 düzeyden derin iç içe geçme ya da girdideki etiket sayısından çok daha fazla öğe. Editör böyle HTML yazmaz. |
Node’da hata, code alanı taşıyan bir SanitizeError’dır:
import { SanitizeError, sanitizeHtml } from '@viveeditor/sanitize'
export function cleanArticle(html: string): string | null {
try {
return sanitizeHtml(html)
} catch (error) {
if (error instanceof SanitizeError) return null
throw error
}
}
PHP’de ise reason değeri SanitizeException::TOO_LARGE ya da SanitizeException::TOO_COMPLEX olan bir SanitizeException’dır:
use Viveeditor\Sanitizer\SanitizeException;
use Viveeditor\Sanitizer\Sanitizer;
try {
$clean = Sanitizer::sanitize($html);
} catch (SanitizeException $error) {
$clean = null;
$reason = $error->reason;
}
Neler korunur
- Bağlantılar
http,https,mailto,telve göreli adresleri tutar ve her zamanrel="noopener noreferrer nofollow"alır. - Görseller
httpsadresi ister.allowBase64veallowRelativeImagesbunu genişletir. - Yerleştirmeler
embeds: trueverilmedikçe kaldırılır. styleyalnızca metin hizalamasını, metin ve vurgu rengini ve tablo genişliklerini tutar.id,name,formve olay işleyicileri hiçbir zaman geçmez.- Betikler, stiller, çerçeveler, SVG ve benzeri öğeler içerikleriyle birlikte kaldırılır.
- Bahsetmeler, formüller ve dipnotlar tam olarak editörün yazdığı biçimde tutulur. Kimliği ya da formülü denetimden geçmeyen, veya bir bağlantının ya da dipnotun içine konmuş bahsetme ve formüller düz metne indirilir. Dipnotlar yalnızca kalın, italik ve bağlantı tutar.
PHP bellek notu
PHP’de ayrıştırıcı içeriden durdurulamaz; bu yüzden bazı kısa ve kötü niyetli girdiler (birkaç on KB kapatılmamış biçim etiketi) denetim çalışmadan önce PHP’nin memory_limit sınırına ulaşabilir. PHP o isteği ölümcül bir hatayla bitirir; bu güvenlidir ama temiz bir istisna değildir.
Temizleme yapan uç noktalarda memory_limit ve max_execution_time değerlerini olağan düzeyde tutun ve istek gövdesinin boyutunu orada sınırlayın.
Ne zaman temizlenmeli
- Kaydederken. Gönderilen HTML’i saklamadan önce temizleyin.
- Gösterirken. Saklanan HTML’i de bir temizleme yardımcısıyla gösterin (Laravel’de
@viveHtml). Böylece temizlemeyi eklemeden önce ya da formlarınızın dışında yazılmış kayıtlar da güvende kalır.
Ham HTML basmayın
Saklanan HTML’i, kaydederken bir kez temizlenmiş olsa bile, temizlemeden ve kaçışsız olarak sayfaya basmayın.
İlgili sayfalar
Editör zaten temiz HTML üretiyor; sunucuda neden yeniden temizlemeliyim?
Çünkü herkes editörü kullanmadan sunucunuza istediği HTML'i gönderebilir. Tarayıcı bir güvenlik sınırı değildir.
Node ve PHP temizleyicileri aynı sonucu verir mi?
Evet. Tek bir izin listesini ve tek bir test derlemini paylaşırlar, aynı çıktıyı verirler.
HTML çok büyük olursa ne olur?
Temizleyici HTML'i kesmek yerine TOO_LARGE hatası fırlatır. Varsayılan sınır 2 MB'tır.