
Sanitize هو أداة تعقيم HTML وCSS تعتمد على قائمة السماح. يزيل كل HTML و/أو CSS من سلسلة نصية باستثناء العناصر والسمات والخصائص التي تختار السماح بها.
باستخدام صيغة تكوين بسيطة، يمكنك إخبار Sanitize بالسماح بعناصر HTML معينة، وسمات معينة داخل تلك العناصر، وحتى بروتوكولات URL معينة داخل السمات التي تحتوي على عناوين URL. يمكنك أيضًا السماح بخصائص CSS محددة، وقواعد @، وبروتوكولات URL في العناصر أو السمات التي تحتوي على CSS. أي HTML أو CSS لا تسمح به صراحةً ستتم إزالته.
يعتمد Sanitize على محلل HTML5 من Nokogiri، الذي يحلل HTML بنفس الطريقة التي تحللها المتصفحات الحديثة، وCrass، الذي يحلل CSS بنفس الطريقة التي تحللها المتصفحات الحديثة. طالما أن تكوين قائمة السماح الخاص بك يسمح فقط بترميز HTML وCSS آمن، فحتى المدخلات الأكثر تشوهًا أو ضارة ستتحول إلى مخرجات آمنة.
[!WARNING]
لا يمكن لـ Sanitize تعقيم محتويات عناصر
<math>أو<svg>بالكامل. عناصر MathML وSVG هي عناصر خارجية لا تتبع قواعد تحليل HTML العادية.افتراضيًا، سيزيل Sanitize جميع عناصر MathML وSVG. إذا أضفت عناصر MathML أو SVG إلى قائمة سماح مخصصة للعناصر، فقد تنشئ ثغرة أمنية في تطبيقك.
gem install sanitize
require 'sanitize'
# Clean up an HTML fragment using Sanitize's permissive but safe Relaxed config.
# This also sanitizes any CSS in `<style>` elements or `style` attributes.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# Clean up an HTML document using the Relaxed config.
Sanitize.document(html, Sanitize::Config::RELAXED)
# Clean up a standalone CSS stylesheet using the Relaxed config.
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# Clean up some CSS properties using the Relaxed config.
Sanitize::CSS.properties(css, Sanitize::Config::RELAXED)
يمكن لـ Sanitize تعقيم الأنواع التالية من المدخلات:
<style>style[!WARNING]
لا يمكن لـ Sanitize تعقيم محتويات عناصر
<math>أو<svg>بشكل كامل. عناصر MathML وSVG هي عناصر خارجية لا تتبع قواعد تحليل HTML العادية.بشكل افتراضي، سيزيل Sanitize جميع عناصر MathML وSVG. إذا أضفت عناصر MathML أو SVG إلى قائمة سماح مخصصة للعناصر، فقد تنشئ ثغرة أمنية في تطبيقك.
الجزء هو مقتطف من HTML لا يحتوي على عنصر <html> على مستوى الجذر.
إذا لم تحدد أي خيارات تكوين، فسيستخدم Sanitize إعداداته الأكثر صرامة بشكل افتراضي، مما يعني أنه سيزيل جميع HTML ويترك فقط النص الآمن.
html = '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'
Sanitize.fragment(html)
# => "foo"
للاحتفاظ بعناصر معينة، أضفها إلى قائمة العناصر المسموح بها.
Sanitize.fragment(html, elements: ['b'])
# => "<b>foo</b>"
عند تعقيم مستند، يجب إدراج عنصر <html> في قائمة السماح. يمكنك أيضًا ضبط :allow_doctype على true للسماح بتعريفات نوع المستند سليمة التكوين.
html = %[
<!DOCTYPE html>
<html>
<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">
</html>
]
Sanitize.document(html,
allow_doctype: true,
elements: ['html']
)
# => "<!DOCTYPE html><html>foo\n \n</html>"
لتعقيم CSS في مقتطف HTML أو مستند، اسمح أولًا بعنصر <style> و/أو السمة style في قائمة السماح. ثم اسمح بخصائص CSS وقواعد @ وبروتوكولات URL التي ترغب في السماح بها في قائمة السماح. يمكنك أيضًا اختيار ما إذا كنت تريد السماح بتعليقات CSS أو حيل التوافق مع المتصفح.
html = %[
<style>
div { color: green; width: 1024px; }
</style>
<div style="height: 100px; width: 100px;"></div>
<p>hello!</p>
]
Sanitize.fragment(html,
elements: ['div', 'style'],
attributes: {'div' => ['style']},
css: {
properties: ['width']
}
)
#=> %[
# <style>
# div { width: 1024px; }
# </style>
#
# <div style=" width: 100px;"></div>
# hello!
# ]
سينظّف Sanitize ورقة أنماط CSS مستقلة أو سلسلة خصائص دون الحاجة إلى استدعاء محلّل HTML.
[!WARNING] يجب استخدام هذا فقط لتنقية CSS لاستخدامها في ملف CSS مستقل. لتنقية CSS بأمان لاستخدامها في سياق HTML، مثل داخل عنصر
<style>أو خاصيةstyle، يجب عليك استخدامSanitize.document()أوSanitize.fragment()مع قائمة سماح مناسبة كما هو موضح في الأقسام السابقة. قد يؤدي عدم القيام بذلك إلى تمكين هجمات حقن HTML.
css = %[
@import url(evil.css);
a { text-decoration: none; }
a:hover {
left: expression(alert('xss!'));
text-decoration: underline;
}
]
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
# => %[
#
#
# a { text-decoration: none; }
#
# a:hover {
#
# text-decoration: underline;
# }
# ]
Sanitize::CSS.properties(%[
left: expression(alert('xss!'));
text-decoration: underline;
], Sanitize::Config::RELAXED)
# => %[
#
# text-decoration: underline;
# ]
بالإضافة إلى الإعدادات الافتراضية فائقة الأمان، يأتي Sanitize مع ثلاث إعدادات مدمجة أخرى يمكنك استخدامها جاهزة أو تكييفها لتلبية احتياجاتك.
يسمح فقط بترميز مضمّن بسيط جدًا. لا روابط، ولا صور، ولا عناصر كتلية.
Sanitize.fragment(html, Sanitize::Config::RESTRICTED)
# => "<b>foo</b>"
يسمح بمجموعة متنوعة من الترميزات بما في ذلك عناصر التنسيق والروابط والقوائم.
لا يُسمح بالصور والجداول، وتقتصر الروابط على بروتوكولات FTP وHTTP وHTTPS وmailto، وتُضاف سمة rel="nofollow" إلى جميع الروابط للتخفيف من البريد العشوائي الخاص بتحسين محركات البحث (SEO).
Sanitize.fragment(html, Sanitize::Config::BASIC)
# => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
يسمح بتنوع أوسع من الترميز، بما في ذلك الصور والجداول، بالإضافة إلى CSS الآمن. لا تزال الروابط محدودة ببروتوكولات FTP وHTTP وHTTPS وmailto، بينما تقتصر الصور على HTTP وHTTPS. في هذا الوضع، لا تتم إضافة rel="nofollow" إلى الروابط.
Sanitize.fragment(html, Sanitize::Config::RELAXED)
# => '<b><a href="http://foo.com/">foo</a></b><img src="https://raw.githubusercontent.com/rgrove/sanitize/main/bar.jpg">'
إذا لم تلبِّ الأوضاع المدمجة احتياجاتك، يمكنك بسهولة تحديد إعدادات مخصصة:
Sanitize.fragment(html,
elements: ['a', 'span'],
attributes: {
'a' => ['href', 'title'],
'span' => ['class']
},
protocols: {
'a' => {'href' => ['http', 'https', 'mailto']}
}
)
يمكنك أيضًا البدء بإحدى إعدادات Sanitize المدمجة ثم تخصيصها لتلبية احتياجاتك.
الإعدادات المدمجة مجمّدة بعمق لمنع الأشخاص من تعديلها (سواء عن طريق الخطأ أو بشكل ضار). لتخصيص إعداد مدمج، أنشئ نسخة جديدة باستخدام Sanitize::Config.merge()، على النحو التالي:
# Create a customized copy of the Basic config, adding <div> and <table> to the
# existing allowlisted elements.
Sanitize.fragment(html, Sanitize::Config.merge(Sanitize::Config::BASIC,
elements: Sanitize::Config::BASIC[:elements] + ['div', 'table'],
remove_contents: true
))
المثال أعلاه يضيف العنصرين <div> و<table> إلى نسخة من قائمة العناصر الموجودة في Sanitize::Config::BASIC. إذا كنت ترغب بدلاً من ذلك في استبدال مصفوفة العناصر بالكامل بمصفوفتك الخاصة، يمكنك حذف عملية +: