Chrome DevTools में सीएसपी और भरोसेमंद टाइप को डीबग करना लागू करना

Kateryna Prokopenko
Kateryna Prokopenko
Alfonso Castaño
Alfonso Castaño

इस ब्लॉग पोस्ट में, हाल ही में लॉन्च किए गए समस्याएं टैब की मदद से, कॉन्टेंट की सुरक्षा नीति (सीएसपी) से जुड़ी समस्याओं को डीबग करने के लिए, DevTools की सहायता को लागू करने के बारे में बताया गया है.

इसे लागू करने का काम, दो इंटर्नशिप के दौरान किया गया था: 1. पहले चरण के दौरान, हमने रिपोर्टिंग का सामान्य फ़्रेमवर्क बनाया और सीएसपी के उल्लंघन से जुड़ी तीन समस्याओं के लिए, समस्या वाले मैसेज डिज़ाइन किए. 2. दूसरे चरण के दौरान, हमने भरोसेमंद टाइप की समस्याओं के साथ-साथ, भरोसेमंद टाइप की डीबगिंग के लिए DevTools की कुछ खास सुविधाएं जोड़ी हैं.

कॉन्टेंट की सुरक्षा के लिए नीति क्या है?

कॉन्टेंट की सुरक्षा के बारे में नीति (सीएसपी) की मदद से, वेबसाइट की सुरक्षा को बेहतर बनाने के लिए, कुछ खास गतिविधियों पर पाबंदी लगाई जा सकती है. उदाहरण के लिए, सीएसपी का इस्तेमाल इनलाइन स्क्रिप्ट को अनुमति न देने या eval को अनुमति न देने के लिए किया जा सकता है. इन दोनों तरीकों से, क्रॉस-साइट स्क्रिप्टिंग (XSS) हमलों के लिए, हमले के दायरे को कम किया जा सकता है. सीएसपी के बारे में ज़्यादा जानने के लिए, यहां पढ़ें.

इस तरह के लिंक पर भरोसा किया गया(टीटी) नीति, सीएसपी की एक नई नीति है. यह डाइनैमिक विश्लेषण की सुविधा चालू करती है. इसकी मदद से, वेबसाइटों पर इंजेक्शन अटैक के बड़े क्लास को व्यवस्थित तरीके से रोका जा सकता है. ऐसा करने के लिए, TT किसी वेबसाइट को अपने JavaScript कोड को कंट्रोल करने में मदद करता है, ताकि innerHTML जैसे DOM सिंक को सिर्फ़ कुछ खास तरह की चीज़ों को असाइन करने की अनुमति दी जा सके.

कोई वेबसाइट, किसी खास एचटीटीपी हेडर को शामिल करके, कॉन्टेंट की सुरक्षा के बारे में नीति को चालू कर सकती है. उदाहरण के लिए, हेडर content-security-policy: require-trusted-types-for 'script'; trusted-types default किसी पेज के लिए टीटी नीति को चालू करता है.

हर नीति इनमें से किसी एक मोड में काम कर सकती है:

  • लागू मोड - जहां नीति का हर उल्लंघन एक गड़बड़ी है,
  • सिर्फ़ रिपोर्ट मोड - यह गड़बड़ी के मैसेज को चेतावनी के तौर पर रिपोर्ट करता है. हालांकि, इससे वेब पेज पर कोई गड़बड़ी नहीं होती.

समस्याएं टैब में, कॉन्टेंट की सुरक्षा के लिए बनी नीति से जुड़ी समस्याओं को लागू करना

इस काम का मकसद, सीएसपी से जुड़ी समस्याओं को डीबग करने के अनुभव को बेहतर बनाना था. नई समस्याओं को हल करते समय, DevTools टीम इस प्रोसेस का इस्तेमाल करती है:

  1. उपयोगकर्ता की कहानियां तय करना. DevTools के फ़्रंट-एंड में, उपयोगकर्ता की उन कहानियों का एक सेट पहचानें जिनमें यह बताया गया हो कि वेब डेवलपर को समस्या की जांच कैसे करनी चाहिए.
  2. फ़्रंट-एंड लागू करना. उपयोगकर्ता की कहानियों के आधार पर, यह पता लगाएं कि फ़्रंट-एंड में समस्या की जांच के लिए कौनसी जानकारी ज़रूरी है. जैसे, कोई मिलता-जुलता अनुरोध, कुकी का नाम, स्क्रिप्ट या एचटीएमएल फ़ाइल में कोई लाइन वगैरह.
  3. समस्या का पता लगाना. ब्राउज़र में उन जगहों की पहचान करें जहां Chrome में समस्या का पता चल सकता है. साथ ही, समस्या की रिपोर्ट करने के लिए उस जगह को इंस्ट्रूमेंट करें. इसमें, दूसरे चरण में दी गई काम की जानकारी शामिल करें.
  4. समस्याओं को सेव और दिखाएं. समस्याओं को सही जगह पर सेव करें और DevTools खुलने के बाद उन्हें उपलब्ध कराएं
  5. समस्याओं का टेक्स्ट डिज़ाइन करना. समस्या के बारे में जानकारी देने वाला ऐसा टेक्स्ट लिखें जिससे वेब डेवलपर को समस्या समझने और उसे ठीक करने में मदद मिल सके

पहला चरण: सीएसपी से जुड़ी समस्याओं के लिए उपयोगकर्ता की कहानियां तय करना

लागू करने का काम शुरू करने से पहले, हमने उपयोगकर्ता की कहानियों के साथ एक डिज़ाइन दस्तावेज़ बनाया, ताकि हम यह बेहतर तरीके से समझ सकें कि हमें क्या करना है. उदाहरण के लिए, हमने यह उपयोगकर्ता की कहानी लिखी:


डेवलपर के तौर पर, मुझे पता चला है कि मेरी वेबसाइट का कुछ हिस्सा ब्लॉक है. इसलिए, मुझे ये काम करने हैं:- - ...यह पता करना है कि मेरी वेबसाइट पर ब्लॉक किए गए iframe / इमेज की वजह CSP है या नहीं - ...यह जानना है कि किसी रिसॉर्स को ब्लॉक करने के लिए, CSP का कौनसा डायरेक्टिव इस्तेमाल किया गया है - ...यह जानना है कि फ़िलहाल ब्लॉक किए गए रिसॉर्स को दिखाने / फ़िलहाल ब्लॉक किए गए js को चलाने के लिए, मेरी वेबसाइट के CSP को कैसे बदला जा सकता है.


इस उपयोगकर्ता की कहानी को एक्सप्लोर करने के लिए, हमने कुछ आसान उदाहरण वेब पेज बनाए. इनमें, सीएसपी के ऐसे उल्लंघन दिखाए गए जिनमें हम दिलचस्पी रखते थे. साथ ही, हमने इस प्रोसेस के बारे में जानने के लिए, उदाहरण के तौर पर बनाए गए पेजों को एक्सप्लोर किया. यहां कुछ वेब पेजों के उदाहरण दिए गए हैं. समस्याएं टैब खुला होने पर डेमो खोलें:

इस प्रोसेस का इस्तेमाल करके, हमें पता चला कि सीएसपी से जुड़ी समस्याओं को डीबग करने के लिए, सोर्स की जगह की जानकारी सबसे ज़्यादा अहम है. हमें यह भी पता चला है कि किसी संसाधन के ब्लॉक होने पर, उससे जुड़े iframe और अनुरोध को तुरंत ढूंढने में भी यह सुविधा मददगार है. साथ ही, DevTools के एलिमेंट पैनल में एचटीएमएल एलिमेंट का सीधा लिंक भी मददगार हो सकता है.

दूसरा चरण: फ़्रंट-एंड लागू करना

हमने इस अहम जानकारी को, Chrome DevTools Protocol (CDP) के ज़रिए DevTools में उपलब्ध कराने के लिए, ड्राफ़्ट के तौर पर तैयार किया:

यहां third_party/blink/public/devtools_protocol/browser_protocol.pdl का कुछ हिस्सा दिया गया है

 type ContentSecurityPolicyIssueDetails extends object
   properties
     # The url not included in allowed sources.
     optional string blockedURL
     # Specific directive that is violated, causing the CSP issue.
     string violatedDirective
     boolean isReportOnly
     ContentSecurityPolicyViolationType contentSecurityPolicyViolationType
     optional AffectedFrame frameAncestor
     optional SourceCodeLocation sourceCodeLocation
     optional DOM.BackendNodeId violatingNodeId

ऊपर दी गई परिभाषा, मुख्य रूप से JSON डेटा-स्ट्रक्चर को कोड में बदलती है. इसे आसान भाषा में लिखा जाता है. इसे पीडीएल (प्रोटोकॉल डेटा लैंग्वेज) कहा जाता है. PDL का इस्तेमाल दो कामों के लिए किया जाता है. सबसे पहले, हम PDL का इस्तेमाल करके TypeScript की परिभाषाएं जनरेट करते हैं. DevTools का फ़्रंट-एंड इन परिभाषाओं पर निर्भर करता है. उदाहरण के लिए, ऊपर दी गई PDL परिभाषा, TypeScript इंटरफ़ेस को जनरेट करती है:

export interface ContentSecurityPolicyIssueDetails {
  /**
  * The url not included in allowed sources.
  */
  blockedURL?: string;
  /**
  * Specific directive that is violated, causing the CSP issue.
  */
  violatedDirective: string;
  isReportOnly: boolean;
  contentSecurityPolicyViolationType: ContentSecurityPolicyViolationType;
  frameAncestor?: AffectedFrame;
  sourceCodeLocation?: SourceCodeLocation;
  violatingNodeId?: DOM.BackendNodeId;
}

दूसरी और शायद सबसे अहम बात यह है कि हम परिभाषा से एक C++ लाइब्रेरी जनरेट करते हैं. यह लाइब्रेरी, C++ Chromium बैक-एंड से इन डेटा स्ट्रक्चर को जनरेट और भेजने के साथ-साथ, उन्हें DevTools फ़्रंट-एंड पर भेजने की प्रोसेस को मैनेज करती है. उस लाइब्रेरी का इस्तेमाल करके, C++ कोड के इस हिस्से का इस्तेमाल करके ContentSecurityPolicyIssueDetails ऑब्जेक्ट बनाया जा सकता है:

protocol::Audits::ContentSecurityPolicyIssueDetails::create()
  .setViolatedDirective(d->violated_directive)
  .setIsReportOnly(d->is_report_only)
  .setContentSecurityPolicyViolationType(BuildViolationType(
      d->content_security_policy_violation_type)))
  .build();

यह तय करने के बाद कि हमें कौनसी जानकारी उपलब्ध करानी है, हमें यह पता लगाना था कि Chromium से यह जानकारी कहां से मिलेगी.

तीसरा चरण: समस्या का पता लगाना

पिछले सेक्शन में बताए गए फ़ॉर्मैट में, Chrome DevTools प्रोटोकॉल (CDP) के लिए जानकारी उपलब्ध कराने के लिए, हमें वह जगह ढूंढनी थी जहां बैक-एंड में जानकारी उपलब्ध थी. सौभाग्य से, CSP कोड में पहले से ही एक समस्या थी, जिसका इस्तेमाल सिर्फ़ रिपोर्ट मोड के लिए किया जाता था. यहां हम इनमें शामिल हो सकते थे: ContentSecurityPolicy::ReportViolation, समस्याओं की रिपोर्ट, रिपोर्टिंग एंड-पॉइंट (ज़रूरी नहीं) को भेजता है. इसे CSP HTTP हेडर में कॉन्फ़िगर किया जा सकता है. हमें जो जानकारी रिपोर्ट करनी थी वह पहले से ही उपलब्ध थी. इसलिए, हमारे इंस्ट्रूमेंटेशन के काम करने के लिए, बैक-एंड में कोई बड़ा बदलाव करना ज़रूरी नहीं था.

चौथा चरण: समस्याओं को सेव और दिखाना

हालांकि, हमें उन समस्याओं की भी शिकायत करनी थी जो DevTools खोलने से पहले हुई थीं. ठीक उसी तरह जैसे कंसोल मैसेज मैनेज किए जाते हैं. इसका मतलब है कि हम समस्याओं की शिकायत सीधे तौर पर फ़्रंट-एंड पर नहीं करते. इसके बजाय, हम एक स्टोरेज का इस्तेमाल करते हैं, जिसमें समस्याओं की जानकारी अपने-आप भर जाती है. भले ही, DevTools खुला हो या नहीं. DevTools खोलने या किसी दूसरे सीडीपी क्लाइंट को अटैच करने के बाद, पहले से रिकॉर्ड की गई सभी समस्याओं को स्टोरेज से फिर से चलाया जा सकता है.

इससे बैक-एंड से जुड़ा काम पूरा हो गया. अब हमें फ़्रंट-एंड में समस्या को दिखाने के तरीके पर ध्यान देने की ज़रूरत थी.

पांचवां चरण: समस्याओं का टेक्स्ट डिज़ाइन करना

समस्याओं के टेक्स्ट को डिज़ाइन करने की प्रोसेस में, हमारी टीम के अलावा कई अन्य टीमें भी शामिल होती हैं. उदाहरण के लिए, हम अक्सर उस टीम की अहम जानकारी पर भरोसा करते हैं जो किसी सुविधा को लागू करती है. इस मामले में, यह सीएसपी टीम होगी. साथ ही, हम DevRel टीम पर भी भरोसा करते हैं. यह टीम यह डिज़ाइन करती है कि वेब डेवलपर किसी खास तरह की समस्या से कैसे निपटें. आम तौर पर, समस्या का टेक्स्ट पूरा होने तक कुछ सुधार किए जाते हैं.

आम तौर पर, DevTools टीम अपने आइडिया के रफ़ ड्राफ़्ट के साथ शुरुआत करती है:


## Header
Content Security Policy: include all sources of your resources in content security policy header to improve the functioning of your site

## General information
Even though some sources are included in the content security policy header, some resources accessed by your site like images, stylesheets or scripts originate from sources not included in content security policy directives.

Usage of content from not included sources is restricted to strengthen the security of your entire site.

## Specific information

### VIOLATED DIRECTIVES
`img-src 'self'`

### BLOCKED URLs
https://imgur.com/JuXCo1p.jpg

## Specific information
https://web.dev/strict-csp/

कई बार कोशिश करने के बाद, हमें ये नतीजे मिले:

ALT_TEXT_HERE

जैसा कि आप देख सकते हैं, सुविधा टीम और डेवलपर रिलेशनशिप टीम को शामिल करने से, जानकारी ज़्यादा साफ़ और सटीक हो जाती है!

आपके पेज पर सीएसपी से जुड़ी समस्याओं को सीएसपी के उल्लंघनों के लिए खास तौर पर बने टैब में भी देखा जा सकता है.

Trusted Types से जुड़ी समस्याओं को डीबग करना

सही डेवलपर टूल के बिना, बड़े पैमाने पर TT का इस्तेमाल करना मुश्किल हो सकता है.

कंसोल पर प्रिंट करने की सुविधा को बेहतर बनाया गया

भरोसेमंद ऑब्जेक्ट के साथ काम करते समय, हम कम से कम उतनी ही जानकारी दिखाना चाहते हैं जितनी जानकारी, भरोसेमंद नहीं ऑब्जेक्ट के लिए दिखाई जाती है. माफ़ करें, फ़िलहाल किसी भरोसेमंद ऑब्जेक्ट को दिखाने पर, रैप किए गए ऑब्जेक्ट के बारे में कोई जानकारी नहीं दिखती.

ऐसा इसलिए होता है, क्योंकि कंसोल में दिखाई गई वैल्यू, डिफ़ॉल्ट रूप से ऑब्जेक्ट पर .valueOf() को कॉल करने से मिलती है. हालांकि, भरोसेमंद टाइप के मामले में, रिटर्न की गई वैल्यू काफ़ी काम की नहीं होती. इसके बजाय, हम आपको .toString() को कॉल करने पर मिलने वाली सुविधाएं देना चाहते हैं. ऐसा करने के लिए, हमें V8 और Blink में बदलाव करने होंगे, ताकि भरोसेमंद ऑब्जेक्ट के लिए खास तरीके से हैंडल किया जा सके.

हालांकि, पुरानी वजहों से V8 में कस्टम हैंडल करने की सुविधा उपलब्ध कराई गई थी, लेकिन इस तरह के तरीके के कई नुकसान हैं. ऐसे कई ऑब्जेक्ट हैं जिन्हें पसंद के मुताबिक दिखाने की ज़रूरत होती है, लेकिन जिनका टाइप JS लेवल पर एक ही होता है. V8, पूरी तरह से JS है. इसलिए, यह वेब एपीआई से जुड़े कॉन्सेप्ट, जैसे कि भरोसेमंद टाइप के बीच अंतर नहीं कर सकता. इसलिए, V8 को इनके बीच अंतर करने के लिए, अपने एम्बेडर (Blink) से मदद लेनी पड़ती है.

इसलिए, कोड के उस हिस्से को Blink या किसी एम्बेडर में ले जाना एक सही विकल्प है. समस्या को हटाने के अलावा, इसकी और भी कई फ़ायदे हैं:

  • एम्बेड करने वाले हर व्यक्ति या कंपनी के पास, ब्यौरा जनरेट करने का अपना तरीका हो सकता है
  • Blink API की मदद से ब्यौरा जनरेट करना बहुत आसान है
  • Blink के पास ऑब्जेक्ट की मूल परिभाषा का ऐक्सेस होता है. इसलिए, अगर जानकारी जनरेट करने के लिए .toString() का इस्तेमाल किया जाता है, तो .toString() को फिर से परिभाषित किए जाने का कोई खतरा नहीं है.

उल्लंघन होने पर रोकें (सिर्फ़ रिपोर्ट मोड में)

फ़िलहाल, टीटी के उल्लंघनों को डीबग करने का सिर्फ़ एक तरीका है. इसके लिए, JS अपवादों पर ब्रेकपॉइंट सेट करें. नीति के उल्लंघन की वजह से, अपवाद ट्रिगर होगा. इसलिए, यह सुविधा आपके लिए काम की हो सकती है. हालांकि, असल दुनिया के उदाहरणों में, आपको टीटी के उल्लंघनों पर ज़्यादा बारीकी से कंट्रोल करने की ज़रूरत होती है. खास तौर पर, हम सिर्फ़ टीटी के उल्लंघनों (अन्य अपवादों को नहीं) के लिए ब्रेक करना चाहते हैं. साथ ही, सिर्फ़ रिपोर्ट मोड में भी ब्रेक करना चाहते हैं और टीटी के अलग-अलग तरह के उल्लंघनों के बीच अंतर करना चाहते हैं.

DevTools में पहले से ही कई तरह के ब्रेकपॉइंट काम करते हैं. इसलिए, इस आर्किटेक्चर को आसानी से बड़ा किया जा सकता है. ब्रेकपॉइंट का नया टाइप जोड़ने के लिए, बैकएंड (Blink), सीडीपी, और फ़्रंटएंड में बदलाव करना ज़रूरी है. हमें एक नया सीडीपी कमांड पेश करना चाहिए. इसे setBreakOnTTViolation कहें. फ़्रंटएंड इस कमांड का इस्तेमाल, बैकएंड को यह बताने के लिए करेगा कि उसे किस तरह के टीटी उल्लंघनों को ठीक करना चाहिए. बैकएंड, खास तौर पर InspectorDOMDebuggerAgent, एक "प्रॉब", onTTViolation() उपलब्ध कराएगा. इसे हर बार तब कॉल किया जाएगा, जब टीटी का उल्लंघन होगा. इसके बाद, InspectorDOMDebuggerAgent यह जांच करेगा कि उल्लंघन की वजह से ब्रेकपॉइंट ट्रिगर होना चाहिए या नहीं. अगर ऐसा है, तो यह फ़्रंटएंड को एक मैसेज भेजेगा, ताकि वह प्रोसेस को रोक सके.

क्या हो चुका है और आगे क्या करना है?

यहां बताई गई समस्याओं के आने के बाद, समस्याएं टैब में काफ़ी बदलाव हुए हैं:

आने वाले समय में, हम समस्याएं टैब का इस्तेमाल करके ज़्यादा समस्याएं दिखाएंगे. इससे, लंबे समय तक Console में गड़बड़ी के ऐसे मैसेज नहीं दिखेंगे जिन्हें पढ़ा नहीं जा सकता.

झलक वाले चैनल डाउनलोड करना

Chrome कैनरी, डेवलपर या बीटा को अपने डिफ़ॉल्ट डेवलपमेंट ब्राउज़र के तौर पर इस्तेमाल करें. इन झलक वाले चैनलों की मदद से, आपको DevTools की नई सुविधाओं का ऐक्सेस मिलता है. साथ ही, इनसे आपको वेब प्लैटफ़ॉर्म के सबसे नए एपीआई की जांच करने में मदद मिलती है. इसके अलावा, इनकी मदद से उपयोगकर्ताओं से पहले ही अपनी साइट पर समस्याओं का पता लगाया जा सकता है!

Chrome DevTools की टीम से संपर्क करना

DevTools से जुड़ी नई सुविधाओं, अपडेट या किसी भी अन्य चीज़ के बारे में चर्चा करने के लिए, यहां दिए गए विकल्पों का इस्तेमाल करें.