
ShadowDOM का उपयोग करके सुरक्षित DOM ट्री पृथक्करण और एनकैप्सुलेशन
⚠️ प्रायोगिक [WIP] - अपने जोखिम पर उपयोग करें (और जानें)
LavaDome पर हाथ आज़माएँ - डेमो ऐप पर जाएँ, कंसोल खोलें, और LavaDome इंस्टेंस के भीतर से रहस्य चुराने के लिए अपनी शक्ति में सब कुछ करें (अपनी सफलता की रिपोर्ट करें)
आज के वेब मानकों के तहत, DOM सबट्रीज़ को सुरक्षित तरीके से चुनिंदा रूप से अलग करने का कोई स्थापित तरीका नहीं है। दूसरे शब्दों में, यदि पक्षकार एक ही JavaScript निष्पादन वातावरण साझा करते हैं, तो हम कुछ पक्षकारों को पहुँच देकर और दूसरों के लिए पहुँच अवरुद्ध करके DOM के अनुभागों तक पहुँच को नियंत्रित नहीं कर सकते।
हम ऐसी दुनिया में रहते हैं जहाँ हम अब अपने स्वयं के ऐप्स में कोड पर भरोसा नहीं कर सकते, और 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 पर (इसलिए उनमें से एक से अधिक का आयात करना आवश्यक नहीं है)।
अधिक जानने के लिए सुरक्षा(रक्षात्मक-कोडिंग) पर जाएँ।
साइड चैनलिंग हमलों और वेब सीमाओं के कारण, रिमोट फ़ॉन्ट्स आयात करना LavaDome के विरुद्ध एक सफल तकनीक हो सकती है। चूँकि यह CSS के दायरे में एम्बेडेड है, इसलिए LavaDome के माध्यम से इस समस्या का समाधान वर्तमान में संभव नहीं है।
सौभाग्य से, इसे CSP के font-src निर्देश का उपयोग करके प्रभावी ढंग से संबोधित किया जा सकता है।
इस प्रकार के हमले को कम करने के लिए, सुनिश्चित करें कि आपका वेब ऐप अज्ञात सर्वरों से फ़ॉन्ट्स लाने की अनुमति नहीं देता है।
अधिक जानने के लिए सुरक्षा(साइड-चैनलिंग) पर जाएँ।
डेवलपर द्वारा LavaDome को प्रदान किया गया पाठ 100% अप्रत्याशित होना चाहिए, अन्यथा उस पर हमला किया जा सकता है और वह लीक हो सकता है।
तो यदि आपका ऐप "your key is 234789" प्रदर्शित करता है, तो इसका अर्थ है कि आपकी DOM संरचना इस प्रकार होनी चाहिए:```html
your key is 234789
और नहीं होना चाहिए:```html
<span> <lavadome>your key is 234789</lavadome> </span>
अधिक जानने के लिए Security(findability) पर जाएँ।
LavaDome को परीक्षण के संदर्भ में एकीकृत करना मुश्किल हो सकता है, क्योंकि चूँकि LavaDome रहस्य को छिपाने का अच्छा काम करता है, यह इसे आपके परीक्षणों से भी काफी अच्छी तरह छिपाता है!
LavaDome को अपने परीक्षण वातावरण में सफलतापूर्वक एकीकृत करने के लिए, आपको LavaDomeDebug से कुछ मदद की आवश्यकता हो सकती है, जिसे @lavamoat/lavadome-core द्वारा export किया गया है:```javascript
// IMPORT/USE FOR TESTING/DEBUGGING PURPOSES ONLY - NEVER IN PRODUCTION!
import { LavaDomeDebug } from '@lavamoat/lavadome-core';
यहाँ कुछ डिबगिंग उपयोगिता विधियाँ हैं जिन्हें `LavaDomeDebug` export करता है और जो `LavaDome` आधारित घटकों के परीक्षण में आपकी सहायता कर सकती हैं:
#### `getTextByRoot()`
किसी `LavaDome` संलग्न root को देखते हुए, `getTextByRoot()` आंतरिक secret को recursively निकालकर पुनर्निर्मित करेगा। ऐसा करने में सक्षम होने के लिए, `LavaDome` instance को मूल रूप से असुरक्षित विकल्प `@unsafeOpenModeShadow` के साथ प्रारंभ किया जाना चाहिए, जो `LavaDome` के आंतरिक shadows को बाहर से accessible बनाता है।
स्वाभाविक रूप से, यह असुरक्षित है और `LavaDome` को पूरी तरह असुरक्षित छोड़ देता है, लेकिन केवल परीक्षण/डिबगिंग उद्देश्यों के लिए उपयोग करना उचित है - सुनिश्चित करें कि इस विकल्प को production में कभी सक्षम न करें!```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
No input content was provided to translate.```bash yarn install && yarn global add serve
## समाधान
[`ShadowDom`](https://web.dev/articles/`ShadowDom`-v1) Web API हमें 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` पृष्ठ पर कहीं और चल रहे JavaScript और CSS से DOM सबट्री को अलग करने के लिए अच्छी तरह काम करता है।
**`LavaDome`** का मूल दृष्टिकोण `ShadowDom` का लाभ उठाना है, साथ ही इसकी [संभावित सुरक्षा कमियों](https://blog.ankursundara.com/shadow-dom/) को ध्यानपूर्वक संबोधित करना है।
**[LavaDome](https://github.com/lavamoat/lavadome/)** को **LavaMoat टूलबॉक्स में एक सुरक्षा उपकरण** के रूप में डिज़ाइन किया गया है, जो केवल फ्रंटएंड-केवल घटकों को लागू करने के लिए है जो विशेष रूप से उपयोगकर्ता और विश्वसनीय कोड के साथ इंटरैक्शन की अनुमति देते हैं, साथ ही ऐप में अविश्वसनीय JavaScript और CSS कोड द्वारा एक्सेस प्रयासों को अवरुद्ध करते हैं।
> [@arxenix](https://github.com/arxenix) को उनके `ShadowDom` सुरक्षा पर [शोध](https://blog.ankursundara.com/shadow-dom/) के लिए शाउट-आउट, जिसने **`LavaDome`** में लागू प्रमुख सुरक्षा सुधारों का आधार प्रदान किया।
## लक्ष्य
**`LavaDome`** परियोजना निम्नलिखित मूल सिद्धांतों का पालन करती है:
### सुरक्षित
हमारी सर्वोच्च प्राथमिकता अभेद्य सुरक्षा प्रदान करना है। हमने `ShadowDom` API को उन्नत सुरक्षा गुणों से लपेटा है ताकि संवेदनशील जानकारी प्रस्तुत करते समय इसका उपयोग सुरक्षित रहे।
इस प्रयास के बारे में अधिक जानने के लिए [सुरक्षा](#Security) देखें।
### DX
हम एक सुव्यवस्थित डेवलपर अनुभव प्रदान करने का प्रयास करते हैं। इसके लिए, हम:
1. जितना संभव हो उतने लोकप्रिय फ्रेमवर्क (React, Angular, आदि) का समर्थन करेंगे;
2. API को आसान और सरल बनाएंगे।
### केवल पढ़ने-योग्य मोड
इस चरण में, हम राइट-मोड का समर्थन करने की योजना नहीं बनाते हैं, जिसका अर्थ है **`LavaDome`** केवल सुरक्षा के लिए सादा टेक्स्ट सामग्री स्वीकार करेगा, और इससे अधिक जटिल कुछ भी नहीं।
ऐसा इसलिए है क्योंकि राइट-मोड का समर्थन करने के लिए एक दुर्गम पृथक DOM लागू करने की आवश्यकता होगी, जो कई सुरक्षा जटिलताओं को पेश करता है जिनका सामना करने के लिए हम अभी तक तैयार नहीं हैं, जैसे:
1. इवेंट लिसनर सुरक्षा - बाहरी कोड को LavaDome आंतरिक नोड्स के लिए निर्धारित इनपुट को इंटरसेप्ट करने से रोकें।
2. ओवरले सुरक्षा - दुर्भावनापूर्ण कोड को **`LavaDome`** पर फ़िशिंग DOM रखने से रोकें, जिससे उपयोगकर्ता संवेदनशील इनपुट गलत इकाई को सौंप दे।
## डिज़ाइन
इस परियोजना की डिज़ाइन जटिलता अधिक नहीं है। हालाँकि, इसके द्वारा लागू सुरक्षा सिद्धांतों की संयुक्त आवश्यकताओं को पूरा करना एक आसान काम नहीं है ([सुरक्षा](#Security) देखें)।
**`LavaDome`** में निम्नलिखित पैकेज शामिल हैं:
### [Core](https://github.com/lavamoat/lavadome/blob/HEAD/packages/core)
उपभोक्ता और संरक्षित पृथक घटक के बीच संचार को मध्यस्थ करने वाली मूल API परत लागू करता है। API का लक्ष्य पृथक घटक के जितना संभव हो उतना बाहरी हेरफेर की अनुमति देना है, बिना उसके भीतर से किसी को भी वास्तविक 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`** को एक सहज और स्वाभाविक डेवलपर अनुभव प्रदान करना होगा, साथ ही होस्ट DOM ट्री के भीतर एनकैप्सुलेटेड शैडो DOM नोड्स के सुरक्षित एकीकरण को सुविधाजनक बनाना होगा, और `ShadowDom` एक DOM-उन्मुख API है जो ठीक इसी उद्देश्य के लिए बनाया गया है। इसने इसे हमारे लक्ष्यों के लिए अधिक उपयुक्त बना दिया।
हालाँकि `ShadowDom` API को इसके निर्माताओं द्वारा आधिकारिक रूप से एक सुरक्षा उपकरण के रूप में समर्थित नहीं किया गया है, इसका कार्यान्वयन अत्यधिक सुरक्षित है, और यह शैडो DOM ट्री के भीतर से कोई भी एनकैप्सुलेटेड जानकारी लीक नहीं करता है, सिवाय बहुत विशिष्ट परिदृश्यों के।
हम मानते हैं कि उन्हीं विशिष्ट परिदृश्यों को ध्यानपूर्वक संबोधित करके, `ShadowDom` को एक सुरक्षित DOM एनकैप्सुलेशन API में उन्नत किया जा सकता है (एक कोशिश के लायक)।
### खतरे
`LavaDome` जैसे `ShadowDom`-आधारित समाधान के साथ मौजूद वर्तमान सुरक्षा खतरों को संबोधित करना महत्वपूर्ण है।
#### 1. इंजेक्शन
डेवलपर्स **`LavaDome`** को HTML/JS/CSS सामग्री प्रदान कर सकते हैं जो लोड होने पर, गलती से या जानबूझकर `ShadowDom` के भीतर से DOM नोड्स को लीक कर सकती है, उदाहरण के लिए रनटाइम पर गतिशील रूप से JavaScript कोड जोड़कर।
इस तकनीक के बारे में अधिक जानने के लिए [@arxenix](https://github.com/arxenix) का [शोध](https://blog.ankursundara.com/shadow-dom/#contenteditable-or-css-injection) पढ़ें।
इस संभावना को रोकने के लिए, **`LavaDome`** शैडो DOM ट्री में DOM नोड्स को बिल्कुल भी स्वीकार नहीं करता है, और केवल सादा टेक्स्ट एनकैप्सुलेट करने का समर्थन करता है। यह हमें उपयोगकर्ता-आपूर्ति की गई HTML/JS/CSS सामग्री पर भरोसा करने में निहित सुरक्षा मुद्दों से निपटने से बचाता है।
हम भविष्य में इस निर्णय पर फिर से विचार करना पसंद करेंगे, क्योंकि हम DOM नोड और सबट्री इनपुट का समर्थन करने के लिए एक स्थिर और सुरक्षित साधन पर शोध कर रहे हैं।
#### 2. खोजनीयता
[find()](https://developer.mozilla.org/en-US/docs/Web/API/Window/find) API डेवलपर्स को उनमें मौजूद टेक्स्ट की खोज करके DOM नोड्स को खोजने और निकालने की अनुमति देता है। यह एकमात्र API है जो अब तक एक `ShadowDom` के भीतर से DOM नोड्स को सफलतापूर्वक लीक करने के लिए जाना जाता है।
<details>
<summary>
Firefox में, टेक्स्ट खोजने के बाद, कोई व्यक्ति <code>getSelection()</code> API का उपयोग करके `ShadowDom` के भीतर से DOM नोड्स लीक कर सकता है, इस प्रकार पूरे विचार से समझौता कर सकता है: <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 API में पूर्वानुमान योग्य सामग्री नहीं भेजनी चाहिए। हालांकि यह स्पष्ट लग सकता है, डेवलपर्स आसानी से 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 के साथ कुछ समस्याओं का समाधान हम कर रहे हैं।
यदि कोई हमलावर सीक्रेट के एक उप-भाग (subset) का अनुमान लगाने में सफल हो जाता है, तो वे पूरे सीक्रेट से समझौता कर सकते हैं (यह मानते हुए कि `getSelection` scoped नोड्स को कैप्चर करता है, जैसे Firefox में होता है)। ऐसा इसलिए क्योंकि उप-भाग की खोज करने पर वह टेक्स्ट नोड लीक हो जाता है जिसमें सीक्रेट का वह उप-भाग शामिल होता है, जिससे हमलावर को पूरे सीक्रेट तक पहुंच मिल जाती है।
जवाबी उपाय के रूप में, **`LavaDome`** सीक्रेट के प्रत्येक अक्षर को उसके अपने `ShadowDom` में संग्रहीत करता है, यह सुनिश्चित करते हुए कि सीक्रेट के एक उप-भाग से समझौता होने पर बाकी हिस्से से समझौता नहीं होगा। इस सुरक्षा उपाय का अतिरिक्त लाभ यह है कि सीक्रेट जितना लंबा होता है और उसमें जितने अधिक संभावित वर्ण विकल्प शामिल होते हैं, हमलावरों के लिए पूरे सीक्रेट को लीक करना उतना ही घातांकीय रूप से कठिन हो जाता है।
फिर भी उल्लंघन (breach) संभव है, लेकिन केवल तब जब हमलावर सभी संभावित वर्णों को एक-एक करके brute-force करता है, मिलने वाले सभी shadows को लीक करता है, और फिर **`LavaDome`** मुख्य होस्ट के भीतर उनकी संबंधित स्थितियों के साथ संरेखित करने के लिए सभी shadows को सही ढंग से क्रमबद्ध (synchronously reorder) करता है।
#### 4. साइड चैनलिंग
एक और जाना-माना हमला ShadowDOM की सामग्री को इनहेरिट होने वाले CSS गुणों जैसे `@font-face` का उपयोग करके किसी दूरस्थ सर्वर पर वर्ण-दर-वर्ण लीक करना है।
[@masatokinugawa](https://github.com/masatokinugawa) द्वारा प्रलेखित निम्नलिखित आक्रमण [शोध](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html) पर विचार करें।
इससे निपटने के लिए, LavaDome पैरेंट Shadow में सभी संभावित वर्ण जोड़ देता है, ताकि ऐसा लीक प्रयास सभी संभावित वर्णों को खोजने में भ्रमित हो जाए, जिससे यह हमला बेकार हो जाता है (देखें https://github.com/LavaMoat/LavaDome/issues/16)।
बेशक, साइड चैनलिंग कई रूपों में आती है, कुछ को संबोधित करना कठिन होता है, जैसे [@securityMB](https://github.com/securityMB) का [शोध](https://research.securitum.com/stealing-data-in-great-style-how-to-use-css-to-attack-web-application/), जिसमें वे लिगेचर फॉन्ट का उपयोग करते हैं ([@masatokinugawa](https://github.com/masatokinugawa) द्वारा एक्सप्लॉइट @ https://github.com/LavaMoat/LavaDome/issues/40)।
इससे निपटने के लिए, LavaDome अपनाने वाले डेवलपर्स से अपेक्षा की जाती है कि वे एक सख्त `font-src` CSP नीति निर्धारित करें ताकि फॉन्ट द्वारा दूरस्थ अनियंत्रित सर्वरों तक लीक संभव न हो।
यह ध्यान देने योग्य है कि यह (सैद्धांतिक रूप से) Safari में उपयोगी नहीं होगा, जहां यह हमला फॉन्ट बनाने के लिए स्थानीय SVG का उपयोग करके किया जा सकता है, इस प्रकार हमलावरों को CSP से स्वतंत्र रहने की अनुमति मिलती है (WIP देखें @ https://github.com/LavaMoat/LavaDome/issues/40#issuecomment-2090318009)।
साइड चैनलिंग हमलों का एक और बेहतरीन उदाहरण - इस बार फॉन्ट का उपयोग नहीं करते हुए - टेक्स्ट फ्रैगमेंट्स का लाभ उठाना है ([@masatokinugawa](https://github.com/masatokinugawa) का [एक्सप्लॉइट](https://github.com/LavaMoat/LavaDome/issues/35) देखें)।
#### 5. रक्षात्मक कोडिंग
एक सुरक्षित समाधान के लिए रक्षात्मक कोडिंग प्रथाओं की आवश्यकता होती है।
- इसके लिए, हमारे द्वारा उपयोग किए जाने वाले सभी नेटिव APIs को आंतरिक उपयोग हेतु कैश किया जाता है, ताकि हमलावर **`LavaDome`** के निष्पादन प्रवाह को तोड़ने के लिए वैश्विक APIs को पुन: कॉन्फ़िगर न कर सकें।
- यदि आप सोर्स कोड में अपरंपरागत शैलीगत विकल्प देखते हैं, तो इसकी अच्छी संभावना है कि वे रक्षात्मक कोडिंग सिद्धांतों से प्रेरित हैं।
- **`LavaDome`** को ऐप में किसी भी अविश्वसनीय स्क्रिप्ट से पहले, और अधिमानतः सभी स्क्रिप्ट्स से पहले शामिल करना **महत्वपूर्ण** है!
- **`LavaDome`** के फ्रेमवर्क संस्करणों का उपयोग करते समय, आपको यह मान लेना चाहिए कि ये फ्रेमवर्क रक्षात्मक रूप से नहीं लिखे गए हैं, और उपयोग किए जाने वाले नेटिव APIs दुर्भावनापूर्ण हस्तक्षेप से सुरक्षित नहीं हैं। सचेत रहें कि बाहरी कोड की सुरक्षा **`LavaDome`** के नियंत्रण से बाहर है।
इसलिए, हम अनुशंसा करते हैं कि ऐसे सुरक्षा समाधानों को हमेशा [@agoric](https://github.com/agoric) द्वारा विकसित [SES](https://github.com/endojs/endo/tree/master/packages/ses#ses) तकनीक के साथ एकीकृत किया जाए। यह [LavaMoat](https://github.com/lavamoat/lavamoat) और [MetaMask](https://github.com/MetaMask/metamask-extension) में अपनाई जाने वाली एक सुरक्षा प्रथा है।
#### 6. React इंटरनल्स प्रोसेसिंग लीकेज
चिंता करने वाली एक और बात (विशेष रूप से React के संदर्भ में) यह तथ्य है कि React घटकों को दिया गया इनपुट उसके द्वारा सक्रिय रूप से वैश्विक ऑब्जेक्ट में लीक किया जा रहा है, जिससे यह ऐप में चल रहे अविश्वसनीय संस्थाओं के लिए आसानी से उपलब्ध हो जाता है (जो `LavaDome` के लक्ष्य को पूरी तरह से कमजोर करता है)।
अधिक जानने के लिए [naugtur](https://github.com/naugtur) की [खोज](https://github.com/LavaMoat/LavaDome/pull/23#issue-2093459897) देखें।
React का समर्थन करने के हमारे इरादे और अपने सीक्रेट को उस पर भरोसा न कर पाने की स्थिति के बीच संतुलन बनाने के लिए, `LavaDomeReact` पैकेज कुछ न्यूनतम (फिर भी सुरक्षित) कार्यक्षमता निर्यात करता है, जो React को सीक्रेट देने से पहले उसे एक विशेष टोकन के साथ बदल देता है, जहां उस टोकन को वापस सीक्रेट में बदलने वाली एकमात्र इकाई `LavaDome` स्वयं है।
यह शक्तिशाली होते हुए भी, दुर्भाग्यवश React उपयोगकर्ताओं को सीक्रेट को `LavaDomeReact` को देने से पहले सक्रिय रूप से यह आदान-प्रदान करना आवश्यक बनाता है।
यदि उपयोगकर्ता को किसी सुविदित टोकन के अलावा कुछ और प्राप्त होता है, तो `LavaDome`-जनित एक अपवाद (exception) फेंका जाता है, ताकि डेवलपर्स को `LavaDomeReact` का सुरक्षित रूप से उपयोग करने के लिए बाध्य किया जा सके।
## अस्वीकरण
यदि आपने ऊपर सब कुछ पढ़ा है, तो आपको अच्छी समझ हो जानी चाहिए कि **`LavaDome`** अभी भी अत्यंत प्रयोगात्मक (experimental) क्यों है। किसी गैर-सुरक्षा सुविधा को सुरक्षित बनाना स्वाभाविक रूप से जोखिम भरा है, लेकिन चूंकि इस समस्या क्षेत्र में कोई अच्छा मौजूदा समाधान नहीं है, हमें लगता है कि यह प्रयास सही दिशा में एक कदम है।
हम फिर भी **`LavaDome`** का उपयोग करने की अनुशंसा करते हैं, क्योंकि यह केवल वर्तमान वेब मानकों पर निर्भर रहने की तुलना में एक स्पष्ट सुधार प्रस्तुत करता है। बस याद रखें कि हमारा समाधान आपके कोड को 'safer' (अधिक सुरक्षित) बनाएगा, लेकिन 'safe' (सुरक्षित) नहीं।
इसके अलावा, कृपया याद रखें: LavaDome आपकी मदद करता है किसी गोपनीय जानकारी (secret) को सुरक्षित रूप से DOM तक पहुंचाने में। LavaDome को दिए जाने से पहले सीक्रेट से समझौता हुआ था या नहीं, यह LavaDome के दायरे से बाहर है।
इसका मतलब है कि जब तक आप इसे LavaDome के साथ साझा नहीं करते, तब तक सीक्रेट की सुरक्षा सुनिश्चित करना आपकी जिम्मेदारी है।
इसे प्राप्त करने का सबसे अच्छा तरीका [SES](https://github.com/endojs/endo/tree/master/packages/ses#ses) / [LavaMoat](https://github.com/lavamoat/lavamoat) का उपयोग करके एक लॉक-डाउन (locked down) वातावरण में चलाना है।