डीओएम पर आधारित क्रॉस-साइट स्क्रिप्टिंग (डीओएम XSS) तब होती है, जब उपयोगकर्ता के कंट्रोल वाले सोर्स (जैसे कि उपयोगकर्ता नाम या यूआरएल फ़्रैगमेंट से लिया गया रीडायरेक्ट यूआरएल) से डेटा, सिंक तक पहुंचता है. सिंक, eval() जैसा कोई फ़ंक्शन या .innerHTML जैसा कोई प्रॉपर्टी सेटर हो सकता है. इसकी मदद से, मनमाना JavaScript कोड चलाया जा सकता है.
डीओएम XSS, वेब सुरक्षा से जुड़ी सबसे आम कमज़ोरियों में से एक है. साथ ही, यह भी आम है कि डेवलपर टीमें गलती से अपने ऐप्लिकेशन में इसे शामिल कर लें. Trusted Types की मदद से, ऐप्लिकेशन को डीओएम XSS की कमज़ोरियों से सुरक्षित रखा जा सकता है. इसके लिए, आपको सुरक्षा की समीक्षा करनी होगी और ऐप्लिकेशन को लिखना होगा. Trusted Types, वेब एपीआई के खतरनाक फ़ंक्शन को डिफ़ॉल्ट रूप से सुरक्षित बनाते हैं. Trusted Types, उन ब्राउज़र के लिए पॉलीफ़िल के तौर पर उपलब्ध हैं जो अब तक इन्हें सपोर्ट नहीं करते.
बैकग्राउंड
डीओएम XSS, कई सालों से वेब सुरक्षा से जुड़ी सबसे आम और खतरनाक कमज़ोरियों में से एक रही है.
क्रॉस-साइट स्क्रिप्टिंग दो तरह की होती है. XSS की कुछ कमज़ोरियां, सर्वर-साइड कोड की वजह से होती हैं. यह कोड, वेबसाइट बनाने वाले एचटीएमएल कोड को असुरक्षित तरीके से बनाता है. अन्य कमज़ोरियों की मुख्य वजह क्लाइंट पर होती है. यहां JavaScript कोड, उपयोगकर्ता के कंट्रोल वाले कॉन्टेंट के साथ खतरनाक फ़ंक्शन कॉल करता है.
सर्वर-साइड XSS से बचने के लिए, स्ट्रिंग को जोड़कर एचटीएमएल जनरेट न करें. इसके बजाय, कॉन्टेक्चुअल-ऑटोएस्केपिंग टेंप्लेटिंग की सुरक्षित लाइब्रेरी का इस्तेमाल करें. साथ ही, गड़बड़ियों को कम करने के लिए, नॉनस पर आधारित कॉन्टेंट की सुरक्षा के लिए बनी नीति का इस्तेमाल करें.
अब ब्राउज़र, Trusted Types का इस्तेमाल करके, क्लाइंट-साइड डीओएम पर आधारित XSS को रोकने में भी मदद कर सकते हैं.
एपीआई के बारे में जानकारी
Trusted Types, जोखिम वाले इन सिंक फ़ंक्शन को लॉक करके काम करते हैं. हो सकता है कि इनमें से कुछ फ़ंक्शन को आपने पहले से ही पहचान लिया हो, क्योंकि ब्राउज़र वेंडर और वेब फ़्रेमवर्क सुरक्षा की वजहों से आपको इन सुविधाओं का इस्तेमाल करने से रोकते हैं.
- स्क्रिप्ट में बदलाव करना:
<script src>और<script>एलिमेंट का टेक्स्ट कॉन्टेंट सेट करना. - किसी स्ट्रिंग से एचटीएमएल जनरेट करना:
- प्लग-इन का कॉन्टेंट चलाना:
- रनटाइम JavaScript कोड कंपाइल करना:
evalsetTimeoutsetIntervalnew Function()
Trusted Types के लिए ज़रूरी है कि आप इन सिंक फ़ंक्शन को डेटा पास करने से पहले, उसे प्रोसेस करें. सिर्फ़ स्ट्रिंग का इस्तेमाल करने से गड़बड़ी होती है, क्योंकि ब्राउज़र को यह नहीं पता होता कि डेटा भरोसेमंद है या नहीं:
anElement.innerHTML = location.href;
यह बताने के लिए कि डेटा को सुरक्षित तरीके से प्रोसेस किया गया है, एक खास ऑब्जेक्ट बनाएं. इसे Trusted Type कहा जाता है.
anElement.innerHTML = aTrustedHTML;
TrustedHTML
ऑब्जेक्ट स्वीकार करता है जिनमें एचटीएमएल स्निपेट की ज़रूरत होती है. अन्य
संवेदनशील सिंक के लिए, TrustedScript और TrustedScriptURL ऑब्जेक्ट भी उपलब्ध हैं.
Trusted Types की मदद से, आपके ऐप्लिकेशन में डीओएम XSS के हमलों का खतरा काफ़ी हद तक कम हो जाता है. इससे सुरक्षा की समीक्षा करना आसान हो जाता है. साथ ही, ब्राउज़र में रनटाइम के दौरान, कोड कंपाइल करते, लिंटिंग करते या बंडल करते समय, टाइप के आधार पर सुरक्षा की जांच लागू की जा सकती है.
Trusted Types का इस्तेमाल करने का तरीका
कॉन्टेंट की सुरक्षा के लिए बनी नीति के उल्लंघन की रिपोर्ट पाने की तैयारी करना
रिपोर्ट कलेक्टर को डिप्लॉय किया जा सकता है. जैसे, ओपन सोर्स reporting-api-processor या go-csp-collector. इसके अलावा, इनके जैसे किसी कमर्शियल टूल का इस्तेमाल किया जा सकता है. ReportingObserver का इस्तेमाल करके, ब्राउज़र में कस्टम लॉगिंग जोड़ी जा सकती है और उल्लंघन को डीबग किया जा सकता है: ReportingObserver
const observer = new ReportingObserver((reports, observer) => {
for (const report of reports) {
if (report.type !== 'csp-violation' ||
report.body.effectiveDirective !== 'require-trusted-types-for') {
continue;
}
const violation = report.body;
console.log('Trusted Types Violation:', violation);
// ... (rest of your logging and reporting logic)
}
}, { buffered: true });
observer.observe();
या इवेंट लिसनर जोड़कर:
document.addEventListener('securitypolicyviolation',
console.error.bind(console));
सिर्फ़ रिपोर्ट करने वाला सीएसपी हेडर जोड़ना
उन दस्तावेज़ों में यह एचटीटीपी रिस्पॉन्स हेडर जोड़ें जिन्हें आपको Trusted Types पर माइग्रेट करना है:
Content-Security-Policy-Report-Only: require-trusted-types-for 'script'; report-uri //my-csp-endpoint.example
अब सभी उल्लंघनों की रिपोर्ट //my-csp-endpoint.example को भेजी जाती है. हालांकि, वेबसाइट काम करती रहती है. अगले सेक्शन में, //my-csp-endpoint.example के काम करने के तरीके के बारे में बताया गया है.
Trusted Types के उल्लंघन की पहचान करना
अब से, जब भी Trusted Types को किसी उल्लंघन का पता चलेगा, ब्राउज़र कॉन्फ़िगर किए गए report-uri को एक रिपोर्ट भेजेगा. उदाहरण के लिए, जब आपका ऐप्लिकेशन innerHTML को कोई स्ट्रिंग पास करता है, तो ब्राउज़र यह रिपोर्ट भेजता है:
{
"csp-report": {
"document-uri": "https://my.url.example",
"violated-directive": "require-trusted-types-for",
"disposition": "report",
"blocked-uri": "trusted-types-sink",
"line-number": 39,
"column-number": 12,
"source-file": "https://my.url.example/script.js",
"status-code": 0,
"script-sample": "Element innerHTML <img src=x"
}
}
इससे पता चलता है कि https://my.url.example/script.js में लाइन 39 पर, innerHTML को <img src=x से शुरू होने वाली स्ट्रिंग के साथ कॉल किया गया था. इस जानकारी से आपको यह पता लगाने में मदद मिलेगी कि कोड के किन हिस्सों की वजह से डीओएम XSS हो सकता है और उनमें बदलाव करने की ज़रूरत है.
उल्लंघन ठीक करना
Trusted Type के उल्लंघन को ठीक करने के लिए, कुछ विकल्प उपलब्ध हैं. नीति का उल्लंघन करने वाले कोड को हटाया जा सकता है , किसी लाइब्रेरी का इस्तेमाल किया जा सकता है, Trusted Type की नीति बनाई जा सकती है या आखिरी विकल्प के तौर पर, डिफ़ॉल्ट नीति बनाई जा सकती है.
नीति का उल्लंघन करने वाले कोड को फिर से लिखना
ऐसा हो सकता है कि नीति के मुताबिक न होने वाले कोड की अब ज़रूरत न हो या उसे उन फ़ंक्शन के बिना फिर से लिखा जा सकता है जिनकी वजह से उल्लंघन होते हैं:
el.textContent = ''; const img = document.createElement('img'); img.src = 'xyz.jpg'; el.appendChild(img);
el.innerHTML = '<img src=xyz.jpg>';
किसी लाइब्रेरी का इस्तेमाल करना
कुछ लाइब्रेरी, Trusted Types पहले से जनरेट करती हैं. इन्हें सिंक फ़ंक्शन को पास किया जा सकता है. उदाहरण के लिए, एचटीएमएल स्निपेट को सैनिटाइज़ करने और XSS पेलोड हटाने के लिए, DOMPurify का इस्तेमाल किया जा सकता है.
import DOMPurify from 'dompurify';
el.innerHTML = DOMPurify.sanitize(html, {RETURN_TRUSTED_TYPE: true});
DOMPurify Trusted Types को सपोर्ट करता है
और सैनिटाइज़ किए गए एचटीएमएल को TrustedHTML ऑब्जेक्ट में रैप करके दिखाता है, ताकि ब्राउज़र
कोई उल्लंघन जनरेट न करे.
Trusted Type की नीति बनाना
कभी-कभी, उल्लंघन की वजह बनने वाले कोड को हटाया नहीं जा सकता. साथ ही, वैल्यू को सैनिटाइज़ करने और आपके लिए Trusted Type बनाने वाली कोई लाइब्रेरी भी नहीं होती. ऐसे मामलों में, Trusted Type ऑब्जेक्ट खुद बनाया जा सकता है.
सबसे पहले, कोई नीति बनाएं. नीतियां, Trusted Types के लिए फ़ैक्ट्री होती हैं. ये अपने इनपुट पर सुरक्षा के कुछ नियम लागू करती हैं:
if (window.trustedTypes && trustedTypes.createPolicy) { // Feature testing
const escapeHTMLPolicy = trustedTypes.createPolicy('myEscapePolicy', {
createHTML: string => string.replace(/\</g, '<')
});
}
इस कोड से myEscapePolicy नाम की एक नीति बनती है. यह नीति, अपने createHTML() फ़ंक्शन का इस्तेमाल करके TrustedHTML ऑब्जेक्ट बना सकती है. तय किए गए नियमों के मुताबिक, एचटीएमएल में < वर्णों को एस्केप किया जाता है, ताकि नए एचटीएमएल एलिमेंट न बन सकें.
नीति का इस्तेमाल इस तरह करें:
const escaped = escapeHTMLPolicy.createHTML('<img src=x onerror=alert(1)>');
console.log(escaped instanceof TrustedHTML); // true
el.innerHTML = escaped; // '<img src=x onerror=alert(1)>'
डिफ़ॉल्ट नीति का इस्तेमाल करना
कभी-कभी, नीति का उल्लंघन करने वाले कोड में बदलाव नहीं किया जा सकता. उदाहरण के लिए, अगर किसी सीडीएन से तीसरे पक्ष की लाइब्रेरी लोड की जा रही है. ऐसे में, a डिफ़ॉल्ट नीति का इस्तेमाल करें:
if (window.trustedTypes && trustedTypes.createPolicy) { // Feature testing
trustedTypes.createPolicy('default', {
createHTML: (string, sink) => DOMPurify.sanitize(string, {RETURN_TRUSTED_TYPE: true})
});
}
default नाम की नीति का इस्तेमाल, उन सभी जगहों पर किया जाता है जहां सिंक में स्ट्रिंग का इस्तेमाल किया जाता है. यह सिंक सिर्फ़ Trusted Type स्वीकार करता है.
कॉन्टेंट की सुरक्षा के लिए बनी नीति को लागू करना
जब आपका ऐप्लिकेशन, उल्लंघन जनरेट करना बंद कर देता है, तब Trusted Types को लागू किया जा सकता है:
Content-Security-Policy: require-trusted-types-for 'script'; report-uri //my-csp-endpoint.example
अब, आपका वेब ऐप्लिकेशन चाहे जितना भी जटिल हो, डीओएम XSS की कमज़ोरी सिर्फ़ आपकी किसी नीति के कोड की वजह से हो सकती है. साथ ही, नीति बनाने की सुविधा को सीमित करके, इसे और भी सुरक्षित बनाया जा सकता है.