
DOMPurify v3.4.13
DOMPurify - أداة تعقيم XSS تعمل على DOM فقط، فائقة السرعة ومتسامحة للغاية، لـ HTML وMathML وSVG. يعمل DOMPurify بإعداد افتراضي آمن، لكنه يوفر الكثير من خيارات الإعداد والخطافات. عرض توضيحي:
DOMPurify
DOMPurify هو مُنقّي XSS يعمل على DOM فقط، سريع للغاية ومتسامح للغاية، لـ HTML و MathML و SVG.
كما أنه سهل الاستخدام للغاية وبسيط للبدء. تمت بداية تطوير DOMPurify في فبراير 2014 وقد وصل الآن إلى الإصدار v3.4.14.
يعمل DOMPurify كـ JavaScript ويعمل في جميع المتصفحات الحديثة (Safari (10+) و Opera (15+) و Edge و Firefox و Chrome - وكذلك أي متصفح آخر يعتمد على Blink أو Gecko أو WebKit). لا يتعطل على MSIE أو المتصفحات القديمة الأخرى. إنه ببساطة لا يفعل شيئًا.
لاحظ أن DOMPurify v2.5.9 هو أحدث إصدار يدعم MSIE. للحصول على تحديثات أمنية مهمة متوافقة مع MSIE، يُرجى استخدام فرع 2.x.
تغطي اختباراتنا الآلية 9 مجموعات من المتصفحات/أنظمة التشغيل على المحركات الحالية (Chromium و Firefox و WebKit عبر Ubuntu و macOS و Windows) مع كل تحديث، كما تعيد مصفوفة منفصلة تشغيل مجموعة الاختبارات على لقطات محركات أقدم (تعود تقريبًا إلى Chromium 110 و Firefox 108 و WebKit 16.4، أي حوالي ثلاث سنوات مضت) بحيث يتم اكتشاف الانحدارات على المتصفحات القديمة أيضًا. كما نقوم بتشغيل Node.js v20 و v22 و v24 و v25 و v26 مع DOMPurify على jsdom. من المعروف أن الإصدارات الأقدم من Node تعمل أيضًا، لكن... لا ضمانات.
DOMPurify كُتب بواسطة خبراء أمنيين لديهم خلفية واسعة في هجمات الويب و XSS. لا تخف. لمزيد من التفاصيل، يُرجى أيضًا قراءة أهدافنا الأمنية ونموذج التهديدات. اقرأها. بجدية. وإذا كنت تستمتع بالتفاصيل الدموية، فإن صفحة فئات الهجمات وسجل الالتفافات تُوثّق حيل تحوير المحلّل، والفضاءات الاسمية، والاستيلاء على الخصائص، والقوالب التي يدافع عنها DOMPurify.
ألهم مشروع DOMPurify إنشاء HTML Sanitizer API، والذي أصبح متاحًا بالفعل في العديد من المتصفحات. وتُوحَّد القدرة نفسها الآن مباشرةً في مواصفات WHATWG HTML.
جدول المحتويات
- ماذا يفعل؟
- كيف أستخدمه؟
- هل توجد نسخة تجريبية؟
- ماذا لو وجدت خللًا أمنيًا؟
- بعض نماذج التنقية من فضلك؟
- ما الذي يُدعم؟
- ماذا عن المتصفحات القديمة مثل Internet Explorer؟
- ماذا عن DOMPurify و Trusted Types؟
- هل يمكنني تخصيص DOMPurify؟
- الإعدادات الدائمة
- الخطافات
- الإعدادات المُزالة
- التكامل المستمر
- القائمة البريدية الأمنية
- من ساهم؟
ماذا يفعل؟
ينقّي DOMPurify HTML ويمنع هجمات XSS. يمكنك إعطاء DOMPurify على سبيل المثال سلسلة مليئة بـ HTML الملوّث وسيعيد سلسلة (ما لم يتم تكوينه بخلاف ذلك) تحتوي على HTML نظيف. سيقوم DOMPurify بإزالة كل ما يحتوي على HTML خطير وبالتالي يمنع هجمات XSS وغيرها من الأشياء السيئة. كما أنه سريع بشكل مذهل. نستخدم التقنيات التي يوفرها المتصفح ونحوّلها إلى مرشح XSS. كلما كان متصفحك أسرع، كلما كان DOMPurify أسرع.
كيف أستخدمه؟
الأمر سهل. فقط قم بتضمين DOMPurify في موقعك.
استخدام النسخة غير المضغوطة (خريطة المصدر متاحة)```html
### استخدام الإصدار الإنتاجي المصغّر والمُختبَر (خريطة المصدر متاحة)```html
<script type="text/javascript" src="dist/purify.min.js"></script>
بعد ذلك يمكنك تعقيم السلاسل النصية عن طريق تنفيذ الكود التالي:```js const clean = DOMPurify.sanitize(dirty);
أو ربما هذا، إذا كنت تحب العمل مع Angular أو ما يشابهه:```js
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize('<b>hello there</b>');
يمكن كتابة HTML الناتج في عنصر DOM باستخدام innerHTML أو في DOM باستخدام document.write(). الأمر متروك لك تمامًا.
لاحظ أنه بشكل افتراضي، نسمح بـ HTML وSVG وMathML. إذا كنت تحتاج إلى HTML فقط، وهو قد يكون حالة استخدام شائعة جدًا، يمكنك إعداد ذلك بسهولة أيضًا:```js
const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });
### هل هناك أي احتمال لإطلاق النار على القدم؟
حسنًا، لاحظ أنه إذا قمت _أولاً_ بتنقية HTML ثم قمت بتعديله _بعد ذلك_، فقد تُبطل بسهولة **تأثيرات التنقية**. إذا مرّرت الترميز المُنقّى إلى مكتبة أخرى _بعد_ التنقية، فتأكد من أن تلك المكتبة لا تعبث بالـ HTML من تلقاء نفسها. راجع [أهداف الأمان ونموذج التهديد](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model) للحصول على وصفات الاستخدام الآمن والوسوم/السمات التي تستحق إعادة النظر، و[فئات الهجمات وتاريخ التحايل](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History) لفهم سبب إبطال المعالجة اللاحقة وتغيير سياق الترميز للتنقية.
### حسنًا، هذا منطقي، لننتقل
بعد تنقية الترميز الخاص بك، يمكنك أيضًا إلقاء نظرة على الخاصية `DOMPurify.removed` لتعرف أي العناصر والسمات تم تجاهلها. يرجى **عدم استخدام** هذه الخاصية لاتخاذ أي قرارات حاسمة متعلقة بالأمان. إنها مجرد أداة مساعدة صغيرة للمهتمين.
### تشغيل DOMPurify على الخادم
يعمل DOMPurify تقنيًا أيضًا على جانب الخادم مع Node.js. ويسعى دعمنا إلى اتباع [دورة إصدارات Node.js](https://nodejs.org/en/about/previous-releases).
يتطلب تشغيل DOMPurify على الخادم وجود DOM، وهذا غالبًا ليس مفاجئًا. عادةً ما تكون [jsdom](https://github.com/jsdom/jsdom) هي الأداة المفضلة، ونحن **ننصح بشدة** باستخدام أحدث إصدار من _jsdom_.
لماذا؟ لأن الإصدارات الأقدم من _jsdom_ معروفة بوجود أخطاء فيها تؤدي إلى XSS _حتى لو_ قام DOMPurify بكل شيء بشكل صحيح بنسبة 100%. توجد **نواقل هجوم معروفة**، على سبيل المثال، في _jsdom v19.0.0_ وقد تم إصلاحها في _jsdom v20.0.0_ - وننصح حقًا بإبقاء _jsdom_ محدّثًا بسبب ذلك.
يرجى أيضًا الانتباه إلى وجود أدوات مثل [happy-dom](https://github.com/capricorn86/happy-dom)، لكنها **لا تُعتبر آمنة** في الوقت الحالي. لا يُنصح حاليًا بدمج DOMPurify مع _happy-dom_، ومن المرجح أن يؤدي ذلك إلى XSS. للاطلاع على خلفية حول كون الـ DOM من جانب الخادم الذي تختاره جزءًا من قاعدة الحوسبة الموثوقة لديك، راجع [فئات الهجمات وتاريخ التحايل](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History).
بخلاف ذلك، لا بأس في استخدام DOMPurify على الخادم. على الأرجح. يعتمد هذا حقًا على _jsdom_ أو أي DOM تستخدمه من جانب الخادم. إذا كان بإمكانك تقبّل ذلك، فهذه هي طريقة تشغيله:```bash
npm install dompurify
npm install jsdom
بالنسبة إلى jsdom (يرجى استخدام نسخة محدّثة)، يجب أن يفي ذلك بالغرض:```js const createDOMPurify = require('dompurify'); const { JSDOM } = require('jsdom');
const window = new JSDOM('').window; const DOMPurify = createDOMPurify(window); const clean = DOMPurify.sanitize('hello there');
أو حتى هذا، إذا كنت تفضل العمل مع imports:```js
import { JSDOM } from 'jsdom';
import DOMPurify from 'dompurify';
const window = new JSDOM('').window;
const purify = DOMPurify(window);
const clean = purify.sanitize('<b>hello there</b>');
إذا كانت لديك مشاكل في جعله يعمل في بيئتك الخاصة، فكّر في الاطلاع على مشروع isomorphic-dompurify الرائع الذي يحل الكثير من المشاكل التي قد يواجهها الأشخاص.```bash npm install isomorphic-dompurify
لم يتم توفير أي محتوى في المدخلات (INPUT) لهذه القطعة. لا يوجد نص للترجمة.```js
import DOMPurify from 'isomorphic-dompurify';
const clean = DOMPurify.sanitize('<s>hello</s>');
هل يوجد عرض توضيحي؟
بالطبع يوجد عرض توضيحي! العب مع DOMPurify
ماذا لو وجدت ثغرة أمنية؟
أولاً، يرجى الاتصال بنا فوراً عبر البريد الإلكتروني حتى نتمكن من العمل على إصلاح. مفتاح PGP
أيضًا، من المحتمل أنك مؤهل للحصول على مكافأة مقابل اكتشاف الثغرات! الأشخاص الرائعون في Fastmail يستخدمون DOMPurify في خدماتهم وأضافوا مكتبتنا إلى نطاق مكافآت اكتشاف الثغرات لديهم. لذا، إذا وجدت طريقة لتجاوز أو إضعاف DOMPurify، فيرجى أيضًا إلقاء نظرة على موقعهم الإلكتروني ومعلومات مكافأة اكتشاف الثغرات.
بعض الأمثلة على التنقية من فضلك؟
كيف يبدو الترميز المُنقّى؟ حسنًا، العرض التوضيحي يوضح ذلك لمجموعة كبيرة من العناصر الخبيثة. لكن دعنا نعرض أيضًا بعض الأمثلة الأصغر!```js
DOMPurify.sanitize(''); // becomes
DOMPurify.sanitize('<g/onload=alert(2)//
'); // becomes DOMPurify.sanitize('
abcdef
'); // becomesabc
DOMPurify.sanitize('<mi//xlink:href="data:x,">'); // becomes DOMPurify.sanitize(''); // becomes| HELLO |
| HELLO |
- <A HREF=//google.com>click
هذه مجرد عينة. للحصول على التصنيف الكامل لفئات الهجمات التي تأتي منها هذه العينات - mutation XSS وnamespace confusion وDOM clobbering وrawtext breakouts وغيرها - راجع [فئات الهجمات وسجل الالتفاف](https://github.com/cure53/DOMPurify/wiki/Attack-Classes-&-Bypass-History).
## ما المدعوم؟
يدعم DOMPurify حاليًا HTML5 وSVG وMathML. يسمح DOMPurify افتراضيًا بسمات CSS وسمات البيانات المخصصة في HTML. يدعم DOMPurify أيضًا Shadow DOM - ويقوم بتعقيم قوالب DOM بشكل تكراري. يتيح لك DOMPurify أيضًا تعقيم HTML لاستخدامه مع واجهة jQuery `$()` و`elm.html()` API دون أي مشاكل معروفة. للحصول على المجموعة الدقيقة للعناصر والسمات المسموح بها افتراضيًا، راجع صفحة الويكي [Default TAGs & ATTRIBUTEs allow-list & blocklist](https://github.com/cure53/DOMPurify/wiki/Default-TAGs-ATTRIBUTEs-allow-list-&-blocklist).
## ماذا عن المتصفحات القديمة مثل Internet Explorer؟
لا يفعل DOMPurify أي شيء على الإطلاق. فهو ببساطة يعيد لك السلسلة النصية التي أدخلتها تمامًا. يكشف DOMPurify عن خاصية تسمى `isSupported`، والتي تخبرك ما إذا كان قادرًا على أداء مهمته، حتى تتمكن من وضع خطتك الاحتياطية الخاصة.
## ماذا عن DOMPurify وTrusted Types؟
في الإصدار 1.0.9، تمت إضافة دعم [Trusted Types API](https://github.com/w3c/webappsec-trusted-types) ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API)) إلى DOMPurify.
في الإصدار 2.0.0، تمت إضافة علامة تهيئة للتحكم في سلوك DOMPurify في هذا الشأن.
عند استخدام `DOMPurify.sanitize` في بيئة تتوفر فيها Trusted Types API ويتم تعيين `RETURN_TRUSTED_TYPE` إلى `true`، فإنه يحاول إرجاع قيمة `TrustedHTML` بدلاً من سلسلة نصية (لا يتغير سلوك خيارات التهيئة `RETURN_DOM` و`RETURN_DOM_FRAGMENT`).
لاحظ أنه لإنشاء سياسة في `trustedTypes` باستخدام DOMPurify، يلزم تعيين `RETURN_TRUSTED_TYPE: false`، لأن `createHTML` يتوقع سلسلة نصية عادية وليس `TrustedHTML`. المثال أدناه يوضح ذلك.```js
window.trustedTypes.createPolicy('default', {
createHTML: (to_escape) =>
DOMPurify.sanitize(to_escape, { RETURN_TRUSTED_TYPE: false }),
});
عند عدم توفير TRUSTED_TYPES_POLICY، يحاول DOMPurify إنشاء سياسة Trusted Types داخلية خاصة به باسم dompurify. إذا كانت صفحتك تعرّف بالفعل سياسة خاصة بها مع CSP صارم (على سبيل المثال trusted-types my-organization) لا تسمح بسياسة باسم dompurify، فسيقوم المتصفح بحظر هذه المحاولة وتسجيل تحذير TrustedTypes policy dompurify could not be created. إلى جانب انتهاك CSP.
لإيقاف DOMPurify عن إنشاء سياسة احتياطية داخلية، مرّر TRUSTED_TYPES_POLICY: null. هذا هو الخيار الصحيح عندما تستدعي DOMPurify.sanitize من داخل createHTML الخاص بسياستك، ويعني أنك لست بحاجة إلى إضافة dompurify إلى قائمة trusted-types المسموح بها في CSP.```js
window.trustedTypes.createPolicy('my-organization', {
createHTML: (input) =>
DOMPurify.sanitize(input, { TRUSTED_TYPES_POLICY: null }),
});
لا **تمرّر** سياسة الالتفاف الخاصة بك إلى DOMPurify كسياسة `TRUSTED_TYPES_POLICY` الخاصة به (على سبيل المثال عبر `DOMPurify.setConfig({ TRUSTED_TYPES_POLICY: myPolicy })`) عندما تستدعي `createHTML` في تلك السياسة `DOMPurify.sanitize` بالفعل. هذا دوران دائري بالتعريف - فالتعقيم سيستدعي السياسة، والسياسة تعقّم باستدعاء DOMPurify مجددًا - وسيرمي DOMPurify خطأ `TypeError` وصفيًا لمنع التكرار اللانهائي. يجب أن تستدعي سياستك الخاصة DOMPurify؛ ولا ينبغي تكوين DOMPurify ليستدعي سياستك.
إذا أردت تطبيق نمط سياسة `default` هذه على صفحة كاملة تلقائيًا - بحيث يتم تعقيم كل مصرف HTML، بما في ذلك التعليمات البرمجية القديمة، وأدوات الطرف الثالث، وآلاف عمليات إسناد `innerHTML` التي لا يمكنك العثور عليها أو إعادة كتابتها بسهولة - فألقِ نظرة على [DOMFortify](https://github.com/cure53/DOMFortify). فهو يثبّت بالضبط سياسة `default` من Trusted Types مدعومة بـ DOMPurify ويرفض مصرفات النصوص البرمجية (`eval`, `script.src`, ...) رفضًا قاطعًا. وهو مشروع منفصل عمدًا: يبقى DOMPurify معقّمًا مركّزًا، بينما يتولى DOMFortify طبقة الإنفاذ على مستوى المستند التي هي خارج نطاق DOMPurify عن قصد.
## هل يمكنني تكوين DOMPurify؟
نعم. قيم التكوين الافتراضية المضمنة جيدة جدًا بالفعل - لكن يمكنك بالطبع تجاوزها. اطّلع على مجلد [`/demos`](https://github.com/cure53/DOMPurify/tree/main/demos) لترى مجموعة من الأمثلة حول كيفية [تخصيص DOMPurify](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this).
قبل توسيع القائمة المسموح بها (`ADD_TAGS`, `ADD_ATTR`, `CUSTOM_ELEMENT_HANDLING`, …) أو تخفيف إعداد افتراضي، يجدر بك تصفّح [الوسوم والسمات التي يجب التفكير فيها مرتين](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model#dangerous-tags-and-attributes-think-twice-before-allow-listing) - فبعضها خطير بطرق غير واضحة.
### إعدادات عامة```js
// strip {{ ... }}, ${ ... } and <% ... %> to make output safe for template systems
// be careful please, this mode is not recommended for production usage.
// allowing template parsing in user-controlled HTML is not advised at all.
// only use this mode if there is really no alternative.
const clean = DOMPurify.sanitize(dirty, { SAFE_FOR_TEMPLATES: true });
// change how e.g. comments containing risky HTML characters are treated.
// be very careful, this setting should only be set to `false` if you really only handle
// HTML and nothing else, no SVG, MathML or the like.
// Otherwise, changing from `true` to `false` will lead to XSS in this or some other way.
const clean = DOMPurify.sanitize(dirty, { SAFE_FOR_XML: false });
التحكم في قوائم السماح وقوائم الحظر لدينا```js
// allow only elements, very strict const clean = DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ['b'] });
// allow only and with style attributes
const clean = DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['b', 'q'],
ALLOWED_ATTR: ['style'],
});
// allow all safe HTML elements but neither SVG nor MathML // note that the USE_PROFILES setting will override the ALLOWED_TAGS setting // so don't use them together const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });
// allow all safe SVG elements and SVG Filters, no HTML or MathML const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { svg: true, svgFilters: true }, });
// allow all safe MathML elements and SVG, but no SVG Filters const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { mathMl: true, svg: true }, });
// change the default namespace from HTML to something different const clean = DOMPurify.sanitize(dirty, { NAMESPACE: 'http://www.w3.org/2000/svg', });
// leave all safe HTML as it is and add elements to block-list const clean = DOMPurify.sanitize(dirty, { FORBID_TAGS: ['style'] });
// leave all safe HTML as it is and add style attributes to block-list const clean = DOMPurify.sanitize(dirty, { FORBID_ATTR: ['style'] });
// extend the existing array of allowed tags and add to allow-list const clean = DOMPurify.sanitize(dirty, { ADD_TAGS: ['my-tag'] });
// extend the existing array of allowed attributes and add my-attr to allow-list const clean = DOMPurify.sanitize(dirty, { ADD_ATTR: ['my-attr'] });
// use functions to control which additional tags and attributes are allowed const allowlist = { one: ['attribute-one'], two: ['attribute-two'], }; const clean = DOMPurify.sanitize( '', { ADD_TAGS: (tagName) => { return Object.keys(allowlist).includes(tagName); }, ADD_ATTR: (attributeName, tagName) => { return allowlist[tagName]?.includes(attributeName) || false; }, } ); //
// prohibit ARIA attributes, leave other safe HTML as is (default is true) const clean = DOMPurify.sanitize(dirty, { ALLOW_ARIA_ATTR: false });
// prohibit HTML5 data attributes, leave other safe HTML as is (default is true) const clean = DOMPurify.sanitize(dirty, { ALLOW_DATA_ATTR: false });
### التحكم في السلوك المتعلق بالعناصر المخصصة```js
// DOMPurify allows to define rules for Custom Elements. When using the CUSTOM_ELEMENT_HANDLING
// literal, it is possible to define exactly what elements you wish to allow (by default, none are allowed).
//
// The same goes for their attributes. By default, the built-in or configured allow.list is used.
//
// You can use a RegExp literal to specify what is allowed or a predicate, examples for both can be seen below.
// When using a predicate function for attributeNameCheck, it can optionally receive the tagName as a second parameter
// for more granular control over which attributes are allowed for specific elements.
// The default values are very restrictive to prevent accidental XSS bypasses. Handle with great care!
const clean = DOMPurify.sanitize(
'<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: null, // no custom elements are allowed
attributeNameCheck: null, // default / standard attribute allow-list is used
allowCustomizedBuiltInElements: false, // no customized built-ins allowed
},
}
); // <div is=""></div>
const clean = DOMPurify.sanitize(
'<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: /^foo-/, // allow all tags starting with "foo-"
attributeNameCheck: /baz/, // allow all attributes containing "baz"
allowCustomizedBuiltInElements: true, // customized built-ins are allowed
},
}
); // <foo-bar baz="foobar"></foo-bar><div is="foo-baz"></div>
const clean = DOMPurify.sanitize(
'<foo-bar baz="foobar" forbidden="true"></foo-bar><div is="foo-baz"></div>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: (tagName) => tagName.match(/^foo-/), // allow all tags starting with "foo-"
attributeNameCheck: (attr) => attr.match(/baz/), // allow all containing "baz"
allowCustomizedBuiltInElements: true, // allow customized built-ins
},
}
); // <foo-bar baz="foobar"></foo-bar><div is="foo-baz"></div>
// Example with attributeNameCheck receiving tagName as a second parameter
const clean = DOMPurify.sanitize(
'<element-one attribute-one="1" attribute-two="2"></element-one><element-two attribute-one="1" attribute-two="2"></element-two>',
{
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: (tagName) => tagName.match(/^element-(one|two)$/),
attributeNameCheck: (attr, tagName) => {
if (tagName === 'element-one') {
return ['attribute-one'].includes(attr);
} else if (tagName === 'element-two') {
return ['attribute-two'].includes(attr);
} else {
return false;
}
},
allowCustomizedBuiltInElements: false,
},
}
); // <element-one attribute-one="1"></element-one><element-two attribute-two="2"></element-two>
التحكم في السلوك المتعلق بقيم URI```js
// extend the existing array of elements that can use Data URIs const clean = DOMPurify.sanitize(dirty, { ADD_DATA_URI_TAGS: ['a', 'area'] });
// extend the existing array of elements that are safe for URI-like values (be careful, XSS risk) const clean = DOMPurify.sanitize(dirty, { ADD_URI_SAFE_ATTR: ['my-attr'] });
### التحكم في قيم السمات المسموح بها```js
// allow external protocol handlers in URL attributes (default is false, be careful, XSS risk)
// by default only http, https, ftp, ftps, tel, mailto, callto, sms, cid, xmpp and matrix are allowed.
const clean = DOMPurify.sanitize(dirty, { ALLOW_UNKNOWN_PROTOCOLS: true });
// allow specific protocol handlers in URL attributes via regex (default is false, be careful, XSS risk)
// by default only (protocol-)relative URLs, http, https, ftp, ftps, tel, mailto, callto, sms, cid, xmpp and matrix are allowed.
// Default RegExp: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
const clean = DOMPurify.sanitize(dirty, {
ALLOWED_URI_REGEXP:
/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
});
التأثير على نوع الإرجاع```js
// return a DOM HTMLBodyElement instead of an HTML string (default is false) const clean = DOMPurify.sanitize(dirty, { RETURN_DOM: true });
// return a DOM DocumentFragment instead of an HTML string (default is false) const clean = DOMPurify.sanitize(dirty, { RETURN_DOM_FRAGMENT: true });
// use the RETURN_TRUSTED_TYPE flag to turn on Trusted Types support if available const clean = DOMPurify.sanitize(dirty, { RETURN_TRUSTED_TYPE: true }); // will return a TrustedHTML object instead of a string if possible
// use a provided Trusted Types policy const clean = DOMPurify.sanitize(dirty, { // supplied policy must define createHTML and createScriptURL TRUSTED_TYPES_POLICY: trustedTypes.createPolicy('dompurify', { createHTML(s) { return s; }, createScriptURL(s) { return s; }, }), });
// opt out of DOMPurify's internal dompurify Trusted Types policy entirely
// (useful when your CSP trusted-types allowlist does not include dompurify)
const clean = DOMPurify.sanitize(dirty, { TRUSTED_TYPES_POLICY: null });
### التأثير على كيفية التعقيم```js
// return entire document including <html> tags (default is false)
const clean = DOMPurify.sanitize(dirty, { WHOLE_DOCUMENT: true });
// disable DOM Clobbering protection on output (default is true, handle with care, minor XSS risks here)
const clean = DOMPurify.sanitize(dirty, { SANITIZE_DOM: false });
// enforce strict DOM Clobbering protection via namespace isolation (default is false)
// when enabled, isolates the namespace of named properties (i.e., `id` and `name` attributes)
// from JS variables by prefixing them with the string `user-content-`
const clean = DOMPurify.sanitize(dirty, { SANITIZE_NAMED_PROPS: true });
// keep an element's content when the element is removed (default is true)
const clean = DOMPurify.sanitize(dirty, { KEEP_CONTENT: false });
// glue elements like style, script or others to document.body and prevent unintuitive browser behavior in several edge-cases (default is false)
const clean = DOMPurify.sanitize(dirty, { FORCE_BODY: true });
// remove all <a> elements under <p> elements that are removed
const clean = DOMPurify.sanitize(dirty, {
FORBID_CONTENTS: ['a'],
FORBID_TAGS: ['p'],
});
// extend the default FORBID_CONTENTS list to also remove <a> elements under <p> elements
const clean = DOMPurify.sanitize(dirty, {
ADD_FORBID_CONTENTS: ['a'],
FORBID_TAGS: ['p'],
});
// change the parser type so sanitized data is treated as XML and not as HTML, which is the default
const clean = DOMPurify.sanitize(dirty, {
PARSER_MEDIA_TYPE: 'application/xhtml+xml',
});
التحكم في مكان التعقيم```js
// use the IN_PLACE mode to sanitize a node "in place", which is much faster depending on how you use DOMPurify const dirty = document.createElement('a'); dirty.setAttribute('href', 'javascript:alert(1)');
const clean = DOMPurify.sanitize(dirty, { IN_PLACE: true }); // see https://github.com/cure53/DOMPurify/issues/288 for more info
هناك حتى [مزيد من الأمثلة هنا](https://github.com/cure53/DOMPurify/tree/main/demos#what-is-this)، توضح كيف يمكنك تشغيل DOMPurify وتخصيصه وتهيئته ليلائم احتياجاتك.
## التكوين الدائم
بدلاً من تمرير نفس التكوين مرارًا وتكرارًا إلى `DOMPurify.sanitize`، يمكنك استخدام طريقة `DOMPurify.setConfig`. سيستمر تكوينك حتى استدعائك التالي لـ `DOMPurify.setConfig`، أو حتى تقوم باستدعاء `DOMPurify.clearConfig` لإعادة تعيينه. تذكر أن هناك تكوينًا نشطًا واحدًا فقط، مما يعني أنه بمجرد تعيينه، يتم تجاهل جميع معاملات التكوين الإضافية التي تمررها إلى `DOMPurify.sanitize`.
## الخطافات (Hooks)
يتيح لك DOMPurify توسيع وظائفه عن طريق إرفاق دالة أو أكثر باستخدام طريقة `DOMPurify.addHook` بأحد الخطافات التالية:
- `beforeSanitizeElements`
- `uponSanitizeElement` (بدون حرف 's' - يُستدعى لكل عنصر)
- `afterSanitizeElements`
- `beforeSanitizeAttributes`
- `uponSanitizeAttribute`
- `afterSanitizeAttributes`
- `beforeSanitizeShadowDOM`
- `uponSanitizeShadowNode`
- `afterSanitizeShadowDOM`
يقوم بتمرير عقدة DOM المعالجة حاليًا، وعند الحاجة، حرفية تحتوي على بيانات العقدة والسمات المؤكدة وإعدادات DOMPurify إلى دالة الاستدعاء. اطّلع على [عرض MentalJS hook](https://github.com/cure53/DOMPurify/blob/main/demos/hooks-mentaljs-demo.html) لترى كيف يمكن استخدام هذه الواجهة البرمجية بشكل أنيق.
_مثال_:```js
DOMPurify.addHook(
'uponSanitizeAttribute',
function (currentNode, hookEvent, config) {
// Do something with the current node
// You can also mutate hookEvent for current node (i.e. set hookEvent.forceKeepAttr = true)
// For other than 'uponSanitizeAttribute' hook types hookEvent equals to null
}
);
ملاحظة حول استدعاء sanitize() من خطاف
DOMPurify.sanitize() ليست قابلة لإعادة الدخول. يرجى عدم استدعائها من داخل خطاف، أو من استدعاء إعداد مثل CUSTOM_ELEMENT_HANDLING.tagNameCheck أو attributeNameCheck. تلك الاستدعاءات تعمل في منتصف تمريرة تعقيم نشطة.
استدعاء sanitize() متداخل يعيد قراءة الإعداد الممرر إليه، وبذلك يستبدل الإعداد الذي لا تزال التمريرة الخارجية تستخدمه. ثم يتم تعقيم باقي المستند الخارجي وفقًا لإعداد الاستدعاء المتداخل بدلاً من إعدادك. وبما أن الاستدعاء المتداخل يعمل عادةً بالإعداد الافتراضي، فإن قائمة السماح الصارمة ALLOWED_TAGS يمكن أن تتسع بصمت إلى القائمة الافتراضية في منتصف المستند، دون أي خطأ أو تحذير.
إذا كنت بحاجة إلى تعقيم ترميز متداخل، على سبيل المثال جزء HTML محمول داخل قيمة سمة، فلديك خياران آمنان. إما أن تضبط إعدادك مرة واحدة عبر DOMPurify.setConfig بدلاً من تمريره في كل استدعاء، لأن الإعداد الثابت مشترك بين الاستدعاء المتداخل ويبقى ساريًا طوال التمريرة؛ أو اجمع الأجزاء أثناء الخطاف وقم بتعقيمها باستدعاء sanitize() منفصل بعد أن يعود الاستدعاء الخارجي.
الإعدادات المُزالة
| الخيار | منذ | ملاحظة |
|---|---|---|
| SAFE_FOR_JQUERY | 2.1.0 | لا حاجة لبديل. |
التكامل المستمر
نستخدم حاليًا GitHub Actions مع Playwright. يتيح لنا ذلك التأكد في كل التزام أن كل شيء يعمل في المتصفحات الحديثة ذات الصلة، كما يعيد سير عمل منفصل مجدول وعند الدمج تشغيل مجموعة الاختبارات على نسخ محركات أقدم بحيث يتم اكتشاف الأعطال في المتصفحات القديمة أيضًا. اطلع على سجلات البناء هنا: https://github.com/cure53/DOMPurify/actions
يمكنك أيضًا تشغيل الاختبارات المحلية بتنفيذ npm run test.
سيتم توقيع جميع الالتزامات ذات الصلة بالمفتاح 0x24BB6BF4 لمزيد من الأمان (منذ 8 أبريل 2016).
التطوير والمساهمة
التثبيت (npm i)
نحن ندعم npm رسميًا. تم تكوين سير عمل GitHub Actions لتثبيت التبعيات باستخدام npm. عند استخدام إصدار قديم ومهجور من npm، لا يمكننا ضمان إصدارات التبعيات المثبتة بشكل كامل، مما قد يؤدي إلى مشكلات غير متوقعة.
السكربتات
نستخدم ESLint عبر xo كجزء من سير العمل قبل الالتزام للمساعدة في ضمان اتساق الكود. بالإضافة إلى ذلك، نستخدم Prettier لتنسيق المصدر وملفات Markdown، ويتم بناء أصول /dist عبر rollup.
هذه هي سكربتات npm الخاصة بنا:
npm run devلبناء حزمة UMD غير مصغّرة أثناء مراقبة المصادر بحثًا عن التغييراتnpm run testلفحص المصادر، وتشغيل الاختبارات عبر jsdom، وتشغيل اختبارات المتصفح في Chromium عبر Playwrightnpm run test:jsdomلتشغيل الاختبارات عبر jsdom فقطnpm run test:happydomلتشغيل مجموعة الاختبارات عبر happy-dom (بيئة غير مدعومة؛ تُبقى كفحص متانة، وليس وعدًا بالتوافق)npm run test:browserلتشغيل الاختبارات عبر Playwright فقطnpm run test:browser:legacyلتشغيل مجموعة الاختبارات على محركات متصفح أقدم (وجّهPW_MODULEإلى تثبيت قديم مثبّت من Playwright؛ انظر.github/workflows/legacy-browsers.yml)npm run test:ciلتشغيل تدفق اختبارات CI لـ jsdom وPlaywrightnpm run test:fuzzلتشغيل أداة تشويش صغيرة تغطيsanitize()وCONFIG
npm run benchلتشغيل معيار الأداء الصغير (micro-benchmark) الخاص بـ jsdom على حزمةdist/purify.cjsالمبنية (قم بالبناء أولاً؛ يدعم--jsonو--compare a.json b.jsonتشغيل A/B عبر الفروع - النتائج اتجاهية، تحقق من الادعاءات الموجهة للمستخدم في متصفحات حقيقية)npm run coverageلبناء حزمة مُجهزة بالأدوات، وتشغيل مجموعة اختبارات jsdom، وكتابة تقرير تغطية HTML محلي للأسطر/الفروع إلىcoverage/index.html(نطاق jsdom فقط، لا يُشغَّل في CI)npm run build:covلبناء حزمة التغطية المُجهزة بالأدوات فقط
npm run lintلفحص المصادر باستخدام ESLint عبر xonpm run formatلتنسيق مصادر JavaScript/TypeScript وMarkdown باستخدام Prettiernpm run format:jsلتنسيق مصادر JavaScript/TypeScript فقطnpm run format:mdلتنسيق ملفات Markdown فقط
npm run buildلبناء تصريحات الأنواع وحزم التوزيع، ثم إصلاح وتنظيف الأنواع المُولّدةnpm run build:typesلإصدار ملفات تصريح TypeScript فقطnpm run build:rollupلبناء جميع حزم Rollupnpm run build:umdلبناء حزمة UMD غير مصغّرة فقطnpm run build:umd:minلبناء حزمة UMD مصغّرة فقطnpm run build:esلبناء حزمة وحدة ES فقطnpm run build:cjsلبناء حزمة CommonJS فقطnpm run build:fix-typesلمعالجة ملفات الأنواع المُولّدة بعد الإنتاجnpm run build:cleanupلتنظيف مخرجات الأنواع المُولّدة المؤقتة
npm run verify-typescriptلتشغيل سكربت التحقق من TypeScriptnpm run commit-amend-buildلتشغيل سكربت المساعدة للمشرفين لتعديل مخرجات البناء
ملاحظة: جميع سكربتات التشغيل تُطلق عبر npm run <script>.
هناك المزيد من سكربتات npm لكنها مدمجة بشكل أساسي مع CI أو يُقصد بها أن تكون "خاصة"، على سبيل المثال لتعديل ملفات توزيع البناء مع كل التزام.
القائمة البريدية الأمنية
نحتفظ بقائمة بريدية تُرسل إشعارًا عندما يتم نشر إصدار أمني حرج من DOMPurify. هذا يعني أنه إذا وجد شخص ما تجاوزًا وقمنا بإصلاحه بإصدار (وهو ما يحدث دائمًا عند اكتشاف تجاوز)، فسيتم إرسال بريد إلى تلك القائمة. يحدث هذا عادةً في غضون دقائق أو بضع ساعات بعد معرفة التجاوز. يمكن الاشتراك في القائمة هنا:
https://lists.ruhr-uni-bochum.de/mailman/listinfo/dompurify-security
لن يتم الإعلان عن الإصدارات ذات الميزات الجديدة في هذه القائمة.
من ساهم؟
لقد ساعد العديد من الأشخاص DOMPurify ليصبح ما هو عليه اليوم، وهم يستحقون التقدير!
offset, Bankde, lukewarlow, DEMON1A, fg0x0, kodareef5, DavidOliver, 1Jesper1, bencalif, trace37labs, eddieran, christos-eth, researchatfluidattacks, frevadiscor, Rotzbua, binhpv, MariusRumpf, prasadrajandran, Cybozu 💛💸, hata6502 💸, openclaw 💸, intra-mart-dh 💸, nelstrom ❤️, hash_kitten ❤️, kevin_mizu ❤️, icesfont ❤️, reduckted ❤️, dcramer 💸, JGraph 💸, baekilda 💸, Healthchecks 💸, Sentry 💸, jarrodldavis 💸, CynegeticIO, ssi02014 ❤️, GrantGryczan, Lowdefy, granlem, oreoshake, tdeekens ❤️, peernohell ❤️, is2ei, SoheilKhodayari, franktopel, NateScarlet, neilj, fhemberger, Joris-van-der-Wel, ydaniv, terjanq, filedescriptor, ConradIrwin, gibson042, choumx, 0xSobky, styfle, koto, tlau88, strugee, oparoz, mathiasbynens, edg2s, dnkolegov, dhardtke, wirehead, thorn0, styu, mozfreddyb ❤️, mikesamuel, jorangreef, jimmyhchan, jameydeorio, jameskraus, hyderali, hansottowirtz, hackvertor, freddyb, flavorjones, djfarrelly, devd, camerondunford, buu700, buildog, alabiaga, Vector919, Robbert, GreLI, FuzzySockets, ArtemBernatskyy, @garethheyes, @shafigullin, @mmrupp, @irsdl,ShikariSenpai, ansjdnakjdnajkd, @asutherland, @mathias, @cgvwzq, @robbertatwork, @giutro, @CmdEngineer_, @avr4mit, davecardwell, Develop-KIM, asamuzaK, fishjojo1 ❤️, Rikuxx0, donmccurdy, hhk-png, elrion018, michalnieruchalski-tiugo, reey, KanhaKanhaiya, odaysec, Akokonunes, alirezarouhbakhsh, Jaybhade وخاصةً @securitymb ❤️ & @masatokinugawa ❤️