
عزل آمن لأشجار DOM وتغليفها باستخدام ShadowDOM
⚠️ تجريبي [WIP] - الاستخدام على مسؤوليتك الخاصة (اعرف المزيد)
جرّب حظك مع LavaDome - قم بزيارة التطبيق التجريبي، افتح وحدة التحكم، وافعل ما بوسعك لسرقة السر من داخل مثيل LavaDome (أبلغ عن نجاحك)
في ظل معايير الويب الحالية، لا توجد طريقة معتمدة لعزل الأشجار الفرعية من DOM بشكل انتقائي وبطريقة آمنة. بعبارة أخرى، لا يمكننا التحكم في الوصول إلى أقسام من DOM بمنح الوصول لبعض الأطراف ومنعه عن آخرين إذا كانوا يتشاركون بيئة تنفيذ JavaScript نفسها.
نحن نعيش في عالم لم يعد بإمكاننا فيه الثقة بالكود الموجود في تطبيقاتنا الخاصة، وتنفيذ نفس الأصل (same-origin) لا يضمن الأمان. لتأمين الأسرار في الواجهة الأمامية، يجب أن نكون قادرين على عرض المحتوى للمستخدم مع ضمان عدم إمكانية اختراقه بواسطة كود JavaScript يعمل تحت نفس الأصل.

حاليًا، يتم ببساطة إرفاق هذا المحتوى الحساس بـ DOM بمجرد تصديره، مما يجعله متاحًا بالكامل لجميع الكيانات التي تعمل داخل التطبيق نفسه. أي أن أجزاء الكود التي لا ينبغي أن يكون لها حق الوصول إلى المفتاح الخاص يمكنها استخراجه بسهولة كنص صريح، طالما أن الكود الخبيث لديه حق الوصول إلى DOM.
لكن اطمئن. نحن نعتقد أن هذه مشكلة قابلة للحل 👇
LavaDome يدعم حاليًا Vanilla JavaScript و React (مع المزيد قريبًا)
import { LavaDome as LavaDomeJavaScript } from '@lavamoat/lavadome-javascript';
const root = document.getElementById('root'); const lavadome = new LavaDomeJavaScript(root); lavadome.text(secret); lavadome.copy(); // copy to clipboard
### [React](https://github.com/lavamoat/lavadome/blob/HEAD/packages/react)```javascript
import { LavaDome as LavaDomeReact, toLavaDomeToken } from '@lavamoat/lavadome-react';
function Secret({ text }) {
const {token, copy} = toLavaDomeCapabilities(text);
return <>
<a onClick={copy}> copy to clipboard </a>
<LavaDomeReact token={token} />
</>;
}
بالإضافة إلى العقدة الجذرية، تقبل جميع المُنشئات وسيطًا اختياريًا ثانيًا للخيارات:```javascript // javascript new LavaDomeJavaScript(root, { // boolean unsafeOpenModeShadow: false, });
// react function Secret({ text }) { const {token} = toLavaDomeCapabilities(text); return <LavaDomeReact token={token} // boolean unsafeOpenModeShadow={false} /> }
### الاستخدام الآمن
نظرًا لقيود النواة الأساسية للويب، لدمج LavaDome بشكل آمن، هناك عدد من الأمور التي يجب الانتباه إليها وتتطلب جهدًا فعّالًا من المطور الذي يقوم بالدمج:
#### ترتيب التنفيذ
LavaDome، مثل أي برنامج أمان آخر بلغة JavaScript، يكون دائمًا عرضة للكود الذي يعمل قبله.
هذا يعني أنه باستثناء الكود الذي نثق به تمامًا، يجب أن يكون LavaDome أول قطعة كود يتم تحميلها في برنامج تطبيق الويب.
في حين أن هذا لا يعني أن على المطور استخدامه فورًا (بل فقط عند الحاجة إليه)، إلا أنه يجب عليه تضمين البرنامج في أقرب وقت ممكن.
للقيام بذلك بشكل صحيح (آمن)، يجب أن يكون أول تعريف import/require في البرنامج بأكمله:```javascript
import '@lavamoat/lavadome-react';
import 'other-stuff';
console.log('Program starts here');
بهذه الطريقة نضمن أن LavaDome يجهّز نفسه للاستخدام الآمن.
لاحظ أن هذا ينطبق بالمثل على باقي حزم LavaDome وليس فقط @lavamoat/lavadome-react (لذا فإن استيراد أكثر من واحدة منها غير ضروري).
انتقل إلى Security(defensive-coding) لمعرفة المزيد.
بسبب هجمات القنوات الجانبية وقيود الويب، يمكن أن يكون استيراد الخطوط البعيدة تقنية ناجحة ضد LavaDome. وبما أنها مدمجة في مجالات CSS، فإن معالجة هذه المشكلة عبر LavaDome غير ممكنة حاليًا.
لحسن الحظ، يمكن معالجة هذا بشكل فعّال باستخدام توجيه font-src الخاص بـ CSP.
للتخفيف من هذا الشكل من الهجوم، تأكد من أن تطبيق الويب الخاص بك لا يسمح بجلب الخطوط من خوادم غير معروفة.
انتقل إلى Security(side-channeling) لمعرفة المزيد.
يجب أن يكون النص المقدم إلى LavaDome من قبل المطور غير قابل للتنبؤ بنسبة 100%، وإلا فقد يتعرض للهجوم والتسريب.
لذا إذا كان تطبيقك يجب أن يعرض "your key is 234789"، فهذا يعني أن بنية DOM لديك يجب أن تكون:```html
your key is 234789
ويجب ألا يكون:```html
<span> <lavadome>your key is 234789</lavadome> </span>
انتقل إلى الأمان (قابلية الاكتشاف) لمعرفة المزيد.
قد يكون دمج LavaDome أمرًا صعبًا في سياق اختباره، لأن LavaDome بما أنه يقوم بعمل جيد في إخفاء السر، فإنه يخفيه جيدًا أيضًا عن اختباراتك!
لدمج LavaDome بنجاح في بيئة الاختبار الخاصة بك، قد تحتاج إلى بعض المساعدة من LavaDomeDebug الذي يتم تصديره بواسطة @lavamoat/lavadome-core:```javascript
// IMPORT/USE FOR TESTING/DEBUGGING PURPOSES ONLY - NEVER IN PRODUCTION!
import { LavaDomeDebug } from '@lavamoat/lavadome-core';
فيما يلي بعض طرق الأدوات المساعدة للتصحيح التي يصدّرها `LavaDomeDebug` لمساعدتك في اختبار المكونات القائمة على `LavaDome`:
#### `getTextByRoot()`
عند إعطاء جذر مرتبط بـ `LavaDome`، سيقوم `getTextByRoot()` باستخراج السر الداخلي وإعادة بنائه بشكل تكراري. وللسماح بذلك، يجب أن يكون مثيل `LavaDome` قد تم تهيئته في الأصل مع الخيار غير الآمن `@unsafeOpenModeShadow`، مما يجعل الظلال الداخلية لـ `LavaDome` قابلة للوصول من الخارج.
بطبيعة الحال، هذا غير آمن ويجعل `LavaDome` عرضة للخطر تمامًا، لكنه منطقي للاستخدام لأغراض الاختبار/التصحيح فقط - تأكد من عدم تفعيل هذا الخيار أبدًا في الإنتاج!```javascript
new LavaDomeJavaScript(root, {
unsafeOpenModeShadow: isThisTestingEnv, // boolean
}).text('123456');
LavaDomeDebug.getTextByRoot(root) === '123456'; // true
stripDistractionFromText()عند استخدام برامج تشغيل الويب للاختبار وتوجيهها لاستخراج النص الداخلي لجذر مثيل LavaDome، فإنها سترجع سلسلة تحتوي على كلٍّ من السر ونص تشتيت LavaDome.
نص التشتيت مهم للأمان (انظر Security(side-channeling))، لكنه يجعل برنامج تشغيل الويب يستخرج أحرفًا ليست جزءًا من السر فعليًا.
لحل ذلك، وبالنظر إلى النص الذي حصل عليه برنامج تشغيل الويب، سيزيل stripDistractionFromText() نص التشتيت منه، تاركًا فقط السلسلة الدقيقة التي تتوقع اختباراتك العثور عليها.
لا تقلق بشأن نص التشتيت، فلن يكون مرئيًا/قابلاً للتفاعل أبدًا للمستخدم في تطبيقك، لكنه يجب أن يكون موجودًا لأسباب أمنية```javascript new LavaDomeJavaScript(root).text('123456'); const element = await driver.findElement('#ROOT'); // driver const text = await element.getText(); // driver LavaDomeDebug.stripDistractionFromText(text) === '123456'; // true
## التطوير
لإعداد بيئة تطوير محلية لـ **`LavaDome`**، استنسخ هذا المستودع وشغّل أحد الأوامر التالية:```bash
npm install && npm install --global serve
```bash
yarn install && yarn global add serve
## الحل
تمكننا واجهة برمجة تطبيقات الويب [`ShadowDom`](https://web.dev/articles/`ShadowDom`-v1) من عزل وتغليف عُقد DOM. ورغم أنه [لم يُصمم كميزة أمنية](https://web.dev/articles/`ShadowDom`-v1#:~:text=Note%3A%20Closed%20shadow%20roots%20are%20not%20very%20useful.%20Some%20developers%20will%20see%20closed%20mode%20as%20an%20artificial%20security%20feature.%20But%20let%27s%20be%20clear%2C%20it%27s%20not%20a%20security%20feature.for%20Closed%20mode%20simply%20prevents%20outside%20JS%20from%20drilling%20into%20an%20element%27s%20internal%20DOM.)، فإن `ShadowDom` يعمل بشكل جيد لعزل الأشجار الفرعية لـ DOM عن JavaScript وCSS التي تعمل في مكان آخر من الصفحة.
يعتمد الأسلوب الأساسي لـ **`LavaDome`** على الاستفادة من `ShadowDom`، مع معالجة [فجواته الأمنية المحتملة](https://blog.ankursundara.com/shadow-dom/) بعناية.
يُقصد بـ **[LavaDome](https://github.com/lavamoat/lavadome/)** أن يكون **أداة أمنية في صندوق أدوات LavaMoat** لبناء مكونات تعمل في الواجهة الأمامية فقط، تسمح حصريًا بالتفاعل مع المستخدم والكود الموثوق، مع حظر محاولات الوصول من كود JavaScript وCSS غير الموثوق في التطبيق.
> تحية إلى [@arxenix](https://github.com/arxenix) على [بحثهم](https://blog.ankursundara.com/shadow-dom/) حول أمان `ShadowDom`، الذي وفّر الأساس لتحسينات أمنية كبيرة تم تنفيذها في **`LavaDome`**.
## الأهداف
يتبع مشروع **`LavaDome`** المبادئ الأساسية التالية:
### الأمان
أولويتنا القصوى هي توفير أمان محكم. لقد أحطنا واجهة برمجة تطبيقات `ShadowDom` بخصائص أمنية متقدمة لجعلها آمنة للاستخدام عند عرض معلومات حساسة.
تفضّل بزيارة [الأمان](#Security) لمعرفة المزيد عن هذا الجهد.
### DX
نسعى إلى توفير تجربة مطوّر سلسة. ولتحقيق ذلك، سنعمل على:
1. دعم أكبر عدد ممكن من الأطر الشائعة (React وAngular وغيرها)؛
2. جعل واجهة برمجة التطبيقات سهلة وبسيطة الاستخدام.
### وضع القراءة فقط
في هذه المرحلة، لا نخطط لدعم وضع الكتابة، مما يعني أن **`LavaDome`** سيقبل فقط محتوى نصيًا عاديًا للحماية، ولا شيء أكثر تعقيدًا من ذلك.
يعود السبب إلى أن دعم وضع الكتابة سيتطلب تنفيذ DOM معزول مستعصٍ، وهو ما يقدّم عدة تعقيدات أمنية لسنا مستعدين لمواجهتها في هذه المرحلة، مثل:
1. أمن Event listeners - منع الكود الخارجي من اعتراض الإدخال الموجّه إلى العقد الداخلية لـ LavaDome.
2. أمن Overlay - منع الكود الخبيث من وضع طبقة DOM تصيّد فوق **`LavaDome`** لحمل المستخدم على تقديم إدخال حساس إلى جهة خاطئة.
## التصميم
التعقيد التصميمي لهذا المشروع ليس عاليًا. غير أن تلبية المتطلبات مجتمعة للمبادئ الأمنية التي ينفّذها يُعدّ مهمة غير تافهة (انظر [الأمان](#Security)).
يتكوّن **`LavaDome`** من الحزم التالية:
### [Core](https://github.com/lavamoat/lavadome/blob/HEAD/packages/core)
تنفّذ طبقة واجهة برمجة التطبيقات الأساسية التي تتوسط التواصل بين المستهلك والمكوّن المعزول المحمي. تهدف واجهة برمجة التطبيقات إلى السماح بأكبر قدر ممكن من التلاعب الخارجي بالمكوّن المعزول دون إتاحة عُقد DOM الفعلية من داخله لأي شخص - ولا حتى لمستهلك LavaDome - للحفاظ على أعلى مستوى أمني ممكن.
بالإضافة إلى ذلك، تتحمل مسؤولية تنفيذ جميع عمليات التحصين الأمني اللازمة لجعل استخدام ميزة `ShadowDom` آمنًا حقًا، على عكس طبيعته الأصلية كونه ليس ميزة أمنية افتراضيًا (انظر [الأمان](#Security)).
> تذكّر: لا يجوز استخدام الحزمة الأساسية في بيئات الإنتاج!
### [JavaScript](https://github.com/lavamoat/lavadome/blob/HEAD/packages/javascript) / [React](https://github.com/lavamoat/lavadome/blob/HEAD/packages/react) / إلخ
تُصدِّر وظائف للمطوّرين لاستهلاك **`LavaDome`** بالطريقة التي يفضّلونها، سواء عبر JavaScript أو كمكوّن React (أو أي منصة أخرى - [اسأل!](https://github.com/lavamoat/lavadome/issues/new?title=**`LavaDome`**+misses+support+for+...))
> ملاحظة: تقديم دعم **`LavaDome`** لأطر العمل يتضمن دمج كود من جهات خارجية لا نتحكم فيها، مما يسبب "بقعًا أمنية عمياء".
> يُرجى قراءة قسم [الأمان](#Security) لمعرفة كيفية البقاء في أقصى درجات الأمان عند استخدام **`LavaDome`** مع أطر عمل من جهات خارجية.
## الأمان
إذا كنت تخطط لاستخدام **`LavaDome`** في مشروع، فإليك الجوانب الأمنية التي يجب أن تكون على دراية بها:
### `ShadowDom` مقابل `iframe`
مرة أخرى، ما زال هذا مشروعًا تجريبيًا، لكننا فكرنا كثيرًا في هذا القرار. البديل الطبيعي لاستخدام `ShadowDom` هو الاستفادة من `iframe`s عبر الأصول المختلفة. اختراق `iframe` عبر الأصول المختلفة أمر مستحيل، وهو معترف به كآلية بالغة الأهمية أمنيًا في مواصفات W3C. وهذا يعني أنه إذا حدث اختراق بطريقة ما، فإنه يُعامل كثغرة أمنية ويُصلح بشكل عاجل من قبل موردي المتصفحات.
لكن الجانب السلبي لهذا النهج هو أن دمج حل قائم على iframe أصعب بكثير، من حيث UI/UX/DX، خاصةً كأداة تهدف إلى التبني الواسع.
يحتاج **`LavaDome`** إلى توفير تجربة مطوّر سلسة وطبيعية مع تسهيل التكامل الآمن لعُقد shadow DOM المعزولة داخل شجرة DOM المضيفة، و`ShadowDom` هي واجهة برمجة تطبيقات موجّهة نحو DOM صُممت بدقة لهذا الغرض. وهذا ما جعلها أكثر ملاءمة لأهدافنا.
في حين أن واجهة برمجة تطبيقات `ShadowDom` ليست معتمدة رسميًا كأداة أمنية من قبل منشئيها، فإن تنفيذها آمن للغاية، ولا تسرّب أي معلومات معزولة من داخل شجرة shadow DOM إلا في سيناريوهات محددة جدًا.
نعتقد أنه من خلال معالجة تلك السيناريوهات تحديدًا بعناية، يمكن تعزيز `ShadowDom` ليصبح واجهة برمجة تطبيقات آمنة لتغليف DOM (الأمر يستحق المحاولة).
### التهديدات
من المهم معالجة التهديدات الأمنية الحالية المرتبطة بحل قائم على `ShadowDom` مثل `LavaDome`.
#### 1. الحقن
قد يزوّد المطوّرون **`LavaDome`** بمحتوى HTML/JS/CSS يمكنه، عند تحميله، تسريب عُقد DOM من داخل `ShadowDom` عن طريق الخطأ أو عن قصد، على سبيل المثال عبر إضافة كود JavaScript ديناميكيًا في وقت التشغيل.
اقرأ [@arxenix](https://github.com/arxenix) [بحثه](https://blog.ankursundara.com/shadow-dom/#contenteditable-or-css-injection) لمعرفة المزيد عن هذه التقنية.
لمنع هذا الاحتمال، لا يقبل **`LavaDome`** عُقد DOM إطلاقًا داخل شجرة shadow DOM، ولا يدعم سوى تغليف نص عادي. هذا يتيح لنا تجنب التعامل مع المشكلات الأمنية الكامنة في الوثوق بمحتوى HTML/JS/CSS المقدَّم من المستخدم.
نود إعادة النظر في هذا القرار مستقبلًا بينما نبحث عن وسيلة مستقرة وآمنة لدعم إدخال عُقد DOM والأشجار الفرعية.
#### 2. القابلية للاكتشاف
تتيح واجهة برمجة تطبيقات [find()](https://developer.mozilla.org/en-US/docs/Web/API/Window/find) للمطوّرين العثور على عُقد DOM واستخراجها عن طريق البحث عن النص الذي تحتويه. هذه هي واجهة برمجة التطبيقات الوحيدة المعروفة حتى الآن التي نجحت في تسريب عُقد DOM من داخل `ShadowDom`.
<details>
<summary>
في Firefox، بعد العثور على النص، يمكن للمرء استخدام واجهة برمجة تطبيقات <code>getSelection()</code> لتسريب عُقد DOM من داخل `ShadowDom`، مما يخرق الفكرة بأكملها: <i>(انقر للتوسيع)</i>
</summary>```js
// defender
const secret = 'AN UNPREDICTABLE SECRET';
const opts = { mode:'closed' };
const root = document.body.firstElementChild.firstElementChild;
const p = document.createElement('p');
const shadow = root.attachShadow(opts);
shadow.append(p);
p.innerText = 'Secret is: ' + secret;
// attacker
setTimeout(() => {
find('Secret is:'); // assuming the Shadow includes predictable text
console.log('stolen secret: ', getSelection().anchorNode.textContent);
});

اقرأ البحث الخاص ب@arxenix لمعرفة المزيد حول هذه التقنية.
للدفاع ضد هذا الهجوم، يجب على مستهلك LavaDome ألا يمرر محتوى يمكن التنبؤ به إلى واجهة برمجة تطبيقات LavaDome. في حين أن هذا قد يبدو واضحًا، قد ينجذب المطورون بسهولة إلى تمرير LavaDome مدخلًا يبدو مثل The secret is: ldsjf9304rjdkn، مما يعرّض أمان LavaDome للخطر تمامًا. وحتى لو كان الجزء ldsjf9304rjdkn غير قابل للتخمين، فإن العبارة الثابتة "The secret is: " يمكن استغلالها لكشف السر، خاصة إذا كانت مكشوفة سابقًا في الـ DOM.
لذلك، عند استخدام LavaDome، يجب على المطورين ألا يمرروا سوى نص غير قابل للتنبؤ بنسبة 100% كمدخل.
document.execCommand('insertHTML', ...) لتحقيق تنفيذ كود تعسفي في النطاق الداخلي لـ`ShadowDom`، واستخدام ذلك للوصول إلى عقد DOM المُغلَّفة. (انقر للتوسيع)
// attacker setTimeout(() => { console.log(1, 'stolen secret:'); const bypass = '<audio/src/onerror=console.log(2,this.nextSibling.innerHTML)>'; find('Secret is:'); // assuming the Shadow includes predictable text // assuming the found node is contenteditable=true document.execCommand('insertHTML', false, bypass); });
<div align="center"><img width="800" src="https://assets.kitploit.com/production/public/readmes/48843/b3f770ae9d6ea6070e8ed984e33a2f4df5112128d21d3c01000dd66ee1143733.png" alt="`ShadowDom` bypass Chromium"/></div>
</details>
للدفاع ضد متجه الهجوم هذا، تقوم **`LavaDome`** بإزالة جميع سمات الأنماط من عناصرها المخصصة باستخدام أعلى سمة نمط ذات أولوية ممكنة (`-webkit-user-modify: unset;`). يضمن هذا أن عناصرها ليست عرضة لحقن CSS خارجي خبيث يطبق سمة `-webkit-user-modify:read-write`، مما قد يجعل عناصر `ShadowDom` قابلة للتحرير (`contenteditable`).
التقنية الثانية المتمثلة في استخدام `contenteditable` كسمة ليست ذات صلة حاليًا، لأن **`LavaDome`** لا تدعم قبول عُقد DOM.
#### 3. قابلية التحديد وتقسيم السر
متجهات الهجوم المذكورة أعلاه ليست مفيدة كثيرًا إذا تم تخفيف [`getSelection`](https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection). من خلال جعل النص الموجود داخل **`LavaDome`** غير قابل للتحديد، نعزز الأمان ضد الحقن المحتمل كما هو موضح أعلاه. يعمل هذا بشكل جيد في Chromium، لكننا نعمل على حل بعض المشكلات مع Firefox.
إذا تمكن المهاجم من تخمين جزء فرعي من السر، فقد يتمكن من اختراق السر بالكامل (بافتراض أن `getSelection` يلتقط العقد النطاقية كما في Firefox). وذلك لأن البحث عن الجزء الفرعي سيكشف عقدة النص التي تتضمن هذا الجزء الفرعي من السر، مما يتيح للمهاجم الوصول إلى السر بأكمله.
كإجراء مضاد، تخزّن **`LavaDome`** كل حرف من السر في `ShadowDom` خاص به، مما يضمن أن اختراق جزء فرعي من السر لن يؤدي إلى اختراق الباقي أيضًا. لهذا الضمان فائدة إضافية تتمثل في جعل تسريب السر بالكامل أصعب بشكل هائل بالنسبة للمهاجمين كلما زاد طوله وزادت الخيارات المحتملة للأحرف التي يتضمنها.
الاختراق ما زال ممكنًا، لكن فقط إذا قام المهاجم بالحث الشامل (brute-force) لجميع الأحرف الممكنة واحدًا تلو الآخر، وسرّب جميع الظلال (shadows) التي يجدها، ثم أعاد ترتيب جميع الظلال بشكل متزامن وصحيح لمطابقة مواقعها النسبية داخل المضيف الرئيسي لـ**`LavaDome`**.
#### 4. القنوات الجانبية
هجوم آخر معروف يتمثل في تسريب محتويات ShadowDOMs باستخدام خصائص CSS القابلة للتوريث مثل `@font-face` إلى خادم بعيد، حرفًا بحرف.
لنأخذ في الاعتبار [البحث](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html) الخاص بالهجوم التالي الموثق من قبل [@masatokinugawa](https://github.com/masatokinugawa).
لمعالجة ذلك، تضيف LavaDome إلى الظل الأصلي (parent Shadow) جميع الأحرف الممكنة، بحيث يتم إرباك محاولة التسريب هذه عند العثور على جميع الأحرف الممكنة، مما يجعل هذا الهجوم عديم الفائدة (انظر https://github.com/LavaMoat/LavaDome/issues/16).
بالطبع، تأتي القنوات الجانبية بأشكال عديدة، بعضها أصعب في المعالجة، مثل [بحث](https://research.securitum.com/stealing-data-in-great-style-how-to-use-css-to-attack-web-application/) [@securityMB](https://github.com/securityMB) حيث يستخدم خطوط الربط (ligature fonts) (استغلال من قبل [@masatokinugawa](https://github.com/masatokinugawa) @ https://github.com/LavaMoat/LavaDome/issues/40).
لمعالجة ذلك، يُتوقع من المطورين الذين يتبنون LavaDome فرض سياسة CSP صارمة لـ`font-src` لضمان عدم إمكانية تسريب البيانات عبر الخطوط إلى خوادم بعيدة غير خاضعة للسيطرة.
من الجدير بالذكر أن هذا (نظريًا) لن يكون مفيدًا في Safari حيث يمكن تنفيذ هذا الهجوم باستخدام SVG محلي لتشكيل الخطوط، مما يسمح للمهاجمين بالبقاء مستقلين عن CSP (انظر العمل قيد التقدم WIP @ https://github.com/LavaMoat/LavaDome/issues/40#issuecomment-2090318009).
مثال رائع آخر على هجمات القنوات الجانبية - هذه المرة بدون استخدام الخطوط - هو استغلال أجزاء النص (text fragments) (انظر [استغلال](https://github.com/LavaMoat/LavaDome/issues/35) [@masatokinugawa](https://github.com/masatokinugawa)).
#### 5. البرمجة الدفاعية
يتطلب الحل الآمن ممارسات برمجية دفاعية.
- لتحقيق هذه الغاية، يتم تخزين جميع واجهات برمجة التطبيقات الأصلية (native APIs) التي نستخدمها مؤقتًا للاستخدام الداخلي، لمنع المهاجمين من إعادة تكوين الواجهات العامة لتخريب مسار تنفيذ **`LavaDome`**.
- إذا لاحظت خيارات أسلوبية غير تقليدية في الكود المصدري، فهناك احتمال كبير أنها ناتجة عن مبادئ البرمجة الدفاعية.
- من **الحيوي** تضمين **`LavaDome`** في التطبيق قبل أي سكربتات لا تثق بها، ويفضل قبل جميع السكربتات!
- عند استخدام إصدارات الأطر (frameworks) من **`LavaDome`**، يجب أن تفترض أن هذه الأطر ليست مكتوبة بشكل دفاعي، وأن واجهات برمجة التطبيقات الأصلية المستخدمة ليست آمنة من التدخل الخبيث. كن محذرًا من أن أمان الكود الخارجي خارج نطاق سيطرة **`LavaDome`**.
لذلك، نوصي دائمًا بدمج حلول الأمان هذه مع تقنية [SES](https://github.com/endojs/endo/tree/master/packages/ses#ses) المطورة من قبل [@agoric](https://github.com/agoric). هذه ممارسة أمنية متبعة في [LavaMoat](https://github.com/lavamoat/lavamoat) و[MetaMask](https://github.com/MetaMask/metamask-extension).
#### 6. تسريب معالجة دواخل React
أمر آخر يجب القلق بشأنه (خاصة في سياق React) هو حقيقة أن المدخلات المقدمة لمكونات React يتم تسريبها بنشاط بواسطتها إلى الكائن العام (global object)، مما يجعلها في متناول الكيانات غير الموثوقة التي تعمل في التطبيق (وهذا يقوض هدف `LavaDome` تمامًا).
راجع [اكتشاف](https://github.com/LavaMoat/LavaDome/pull/23#issue-2093459897) [naugtur](https://github.com/naugtur) لمعرفة المزيد.
لموازنة نيتنا في دعم React مع عدم قدرتنا على الوثوق بها بسرنا، تصدّر حزمة `LavaDomeReact` بعض الوظائف البسيطة (والآمنة مع ذلك) لاستبدال السر برمز مميز (token) خاص قبل تمريره إلى React، حيث يكون الكيان الوحيد الذي يمكنه استبدال هذا الرمز مرة أخرى بالسر هو `LavaDome` نفسها.
على الرغم من قوتها، يتطلب هذا للأسف من مستخدمي React القيام بالاستبدال بنشاط قبل تمرير السر إلى `LavaDomeReact`.
إذا استلم المستخدم أي شيء آخر غير رمز معروف جيدًا، فسيتم إلقاء استثناء مولّد من `LavaDome`، لإجبار المطورين على استخدام `LavaDomeReact` بأمان.
## إخلاء المسؤولية
إذا قرأت كل ما سبق، يجب أن تكون لديك فكرة جيدة عن سبب كون **`LavaDome`** لا تزال تجريبية للغاية. جعل ميزة غير أمنية آمنة هو أمر محفوف بالمخاطر بطبيعته، ولكن نظرًا لعدم وجود حلول جيدة قائمة في هذه المساحة، فإننا نرى أن هذه المحاولة تمثل خطوة في الاتجاه الصحيح.
ما زلنا نوصي باستخدام **`LavaDome`**، لأنها تمثل تحسنًا لا لبس فيه مقارنة بالاعتماد فقط على معايير الويب الحالية. فقط تذكر أن حلنا سيجعل الكود الخاص بك "أكثر أمانًا"، وليس "آمنًا".
بالإضافة إلى ذلك، تذكر من فضلك: تساعدك LavaDome على إحضار سر إلى DOM بشكل آمن. ما إذا كان السر قد تم اختراقه أم لا قبل تمريره إلى LavaDome هو خارج نطاق LavaDome.
هذا يعني أن ضمان سلامة السر حتى اللحظة التي تشاركه فيها مع LavaDome هو مسؤوليتك.
أفضل طريقة لتحقيق ذلك هي التشغيل في بيئة مقفلة باستخدام [SES](https://github.com/endojs/endo/tree/master/packages/ses#ses) / [LavaMoat](https://github.com/lavamoat/lavamoat).