आँकड़ों और विज्ञापन के लिए कुकीज़
हम आँकड़ों और विज्ञापन के लिए कुकीज़ इस्तेमाल करते हैं, दोनों Google को जाती हैं। मना करने से आपको दिखने वाली किसी चीज़ में कोई फ़र्क़ नहीं पड़ता।निजता पेज पढ़ें
कोई पता चिपकाइए और उसे वैसे देखिए जैसे ब्राउज़र देखता है: scheme, host, port, path, query और fragment, और साथ में query का हर पैरामीटर अपनी पंक्ति में। यह ब्राउज़र में पहले से मौजूद parser से तोड़ा जाता है — वही जो तय करता है कि कोई क्लिक असल में कहाँ ले जाता है — न कि किसी regular expression से, जो ठीक किनारे वाली हालतों में अलग फ़ैसला करती।
कहाँ चलता है
कुछ भी अपलोड नहीं होता, क्योंकि कोई फ़ाइल है ही नहीं — गणना इसी पन्ने में होती है।
न कतार, न खाता
यह उतनी ही तेज़ी से जवाब देता है जितनी आपकी मशीन देती है, और कभी नहीं पूछता कि आप कौन हैं।
जितनी बार चाहें
न कुछ गिना जाता है, न कोई सीमा है — दोबारा जवाब देने में हमारा कुछ ख़र्च नहीं होता।
यह विभाजन अंतर्निहित `URL` इंटरफ़ेस से आता है, न कि हाथ से लिखी किसी regular expression से। यही वह जगह है जहाँ इस क़िस्म के औज़ार अलग हो जाते हैं: WHATWG का विनिर्देश ऐसे नियमों से भरा है जिनका ख़ुद बनाते समय शक तक नहीं होता, और दिलचस्प ग़लतियाँ उन्हीं नियमों में रहती हैं।
एक उदाहरण host का सामान्यीकरण है: बड़े-छोटे अक्षर एक कर दिए जाते हैं, आख़िर का बिंदु हटा दिया जाता है और अंतरराष्ट्रीय नाम Punycode में बदल दिए जाते हैं। Regular expression सब कुछ जस का तस छोड़ देती है, और फिर दो ऐसे पतों के बीच अंतर बताती है जो किसी भी ब्राउज़र के लिए एक ही हैं।
`https://[email protected]/` में host `dhokha.example` है, `udaharan.example` नहीं: `@` से पहले की हर चीज़ credentials है। यह मानक के अनुरूप है और मौजूद सबसे पुरानी phishing तरकीबों में से एक की बुनियाद है, क्योंकि नज़र पहले जाने-पहचाने नाम पर ही ठहर जाती है।
इसीलिए यहाँ host की अपनी पंक्ति है। जो किसी संदिग्ध पते की जाँच कर रहा है उसे गिनना नहीं पड़ता, बस पढ़ना पड़ता है कि वह असल में कहाँ इशारा करता है। और इसी पोटली में यह भी है: `udaharan.example.dhokha.example` जैसा नाम भी `dhokha.example` का ही पता है, क्योंकि आख़िरी दो लेबल ही तय करते हैं।
पता तोड़ा जाता है, खोला नहीं जाता। Host को कोई रिक्वेस्ट नहीं जाती, कोई पूर्वावलोकन नहीं है और redirect हल नहीं किए जाते, और यह एक फ़ैसला है, कोई ग़ैरमौजूद सुविधा नहीं: जो किसी संदिग्ध URL की जाँच कर रहा है वह सबसे आख़िरी व्यक्ति है जो चाहेगा कि औज़ार उस पर जाकर आए।
जाने से एक बात ज़ाहिर भी हो जाती। रिक्वेस्ट किसी सर्वर से निकलती, उसका IP और समय दूसरी तरफ़ के लॉग में दर्ज होते, और एक बार इस्तेमाल होने वाले पते के साथ — कोई पुष्टि-लिंक, कोई पासवर्ड रीसेट — वह रास्ते में ही ख़र्च हो जाता। तोड़ना निरापद क्रिया है, और यहाँ वही एक होती है।
Path में पड़ा `..` तोड़ते समय हल हो जाता है: `/docs/a/../b` `/docs/b` बन जाता है। यह सामान्यीकरण का हिस्सा है और ऐसी चीज़ नहीं जो यह औज़ार जोड़ता हो — कोई भी ब्राउज़र रिक्वेस्ट भेजने से पहले यही करता है, और सर्वर मूल रूप कभी देखता ही नहीं।
यह हर उस चीज़ में मायने रखता है जो path की तुलना करती है या उन पर अनुमतियाँ तय करती है। जो किसी पहुँच-नियम को सामान्यीकृत path के बजाय कच्ची स्ट्रिंग के सामने जाँचता है वह उस चीज़ से अलग चीज़ जाँच रहा है जो असल में माँगी जाएगी — वही छेद जिसे दशकों से path traversal कहा जाता है।
`#` के बाद की हर चीज़ ब्राउज़र में रह जाती है। वह किसी रिक्वेस्ट में नहीं दिखती, किसी सर्वर तक नहीं पहुँचती और किसी access log में दर्ज नहीं होती। यह HTTP का गुण है, कोई निजता-सुविधा नहीं, और यह दोनों तरफ़ काटता है।
यह काम का है क्योंकि वहाँ रखा मान सर्वर तक नहीं जाता — ऐतिहासिक रूप से यही वजह थी कि OAuth के token fragment में सफ़र करते थे। यह असुविधाजनक है क्योंकि वह फिर भी इतिहास में, कुछ स्क्रिप्टों की referrer-शृंखला में और साझा किए गए हर लिंक में रह जाता है। «सर्वर तक नहीं पहुँचता» का मतलब «निजी है» नहीं होता।
अगर port उस scheme का सामान्य वाला हो — https में 443, http में 80 — तो parser उसे छोड़ देता है, क्योंकि वह अनावश्यक है। `https://udaharan.example:443/` और `https://udaharan.example/` एक ही पता हैं, और सामान्यीकरण इसे दिखा देता है।
दो URL स्ट्रिंग की तुलना विफल होने की यह आम व्याख्या है, भले दोनों का मतलब एक ही हो। जो पतों की तुलना करता है उसे पहले उन्हें किसी parser से गुज़ारकर सामान्यीकृत रूप की तुलना करनी चाहिए, यानी ठीक वही जो यहाँ पंक्तियों में दिखता है।
`htp://udaharan.example` जैसी टाइपिंग की ग़लती मना नहीं की जाती: उसे `htp` scheme वाले पते की तरह पढ़ा जाता है। यह parser का दोष नहीं है — विनिर्देश किसी भी scheme को मानता है, क्योंकि उनके सैकड़ों हैं: `mailto:`, `tel:`, `git+ssh:`, `upi:`, और कोई नहीं जान सकता कि आपकी दुनिया में कौन-से वैध हैं।
व्यवहार में: अगर यहाँ ऐसा scheme दिखे जिसकी आपने उम्मीद नहीं की थी, तो आपको अपनी टाइपिंग की ग़लती मिल गई। और इसका यह मतलब भी है कि «क्या यह तोड़ा जा सकता है?» वाली जाँच यह जाँच नहीं है कि पता वेब की ओर इशारा करता है; उसके लिए scheme को एक साफ़ सूची से मिलाना पड़ता है।
`https://upyokta:paasword@host/` वाला रूप आज भी मौजूद है, और पुरानी स्क्रिप्टों में, डेटाबेस की connection स्ट्रिंग में और दस्तावेज़ों के उदाहरणों में मिलता है। ब्राउज़रों ने उसका इस्तेमाल सीमित कर दिया है क्योंकि वह phishing के लिए आदर्श था, पर लाइब्रेरियाँ और कमांड-लाइन के औज़ार उसे आज भी क़बूल करते हैं।
यहाँ उपयोक्ता का नाम दिखाया जाता है और पासवर्ड नहीं: उसकी जगह सिर्फ़ यह संकेत आता है कि कोई पासवर्ड मौजूद है। वजह मामूली है और फिर भी गिनती की है — ये नतीजे अक्सर किसी स्क्रीनशॉट में या किसी टिकट में पहुँच जाते हैं, और जो पासवर्ड पहले से आपके पास है उसे दोबारा छापने की ज़रूरत नहीं।
देवनागरी वाला host Punycode में बदल जाता है: `भारत.example` `xn--h2brj9c.example` बन जाता है। DNS में सचमुच यही रूप मौजूद है, क्योंकि नाम-तंत्र सिर्फ़ ASCII जानता है; पढ़ने लायक़ लिखावट ब्राउज़र की दृश्य सहायता है।
जो असल में पूछा जा रहा है उसे दिखा देने की अपनी सुरक्षा-उपयोगिता है। Homograph हमले दूसरी लिपियों के ऐसे अक्षर इस्तेमाल करते हैं जो लातीनी जैसे दिखते हैं; Punycode रूप में वे तुरंत आँख में चुभते हैं, क्योंकि जाने-पहचाने नाम की जगह अक्षरों की खिचड़ी दिखती है। भारत में `.भारत` जैसे IDN चलन में हैं, इसलिए यह पंक्ति यहाँ सजावट नहीं है।
Origin तीन चीज़ों का जोड़ है: scheme, host और port। ब्राउज़र की सुरक्षा की लगभग हर सीमा इसी इकाई पर खिंची है — cookie, localStorage, CORS और same-origin नीति सब यही देखते हैं, path नहीं। इसीलिए उसकी अपनी पंक्ति है।
नतीजा यह है कि `https://udaharan.example/a` और `https://udaharan.example/b` एक ही origin हैं, जबकि `http://udaharan.example/a` दूसरा origin है, सिर्फ़ scheme बदलने से। जो CORS की किसी त्रुटि का पीछा कर रहा है वह आम तौर पर इसी पंक्ति को देखकर समझ जाता है कि दो पते जिन्हें उसने एक जैसा मान लिया था, ब्राउज़र के लिए एक जैसे थे ही नहीं।
जिन URL की जाँच की जाती है वे आम तौर पर कहीं से आती हैं: किसी लॉग से, किसी संदिग्ध संदेश से, किसी सपोर्ट टिकट से। उनमें अक्सर session की पहचानें, पुष्टि के token और कभी-कभी पैरामीटर बने ईमेल पते होते हैं। चूँकि विभाजन पन्ने पर ही होता है, उनमें से कुछ भी हम तक नहीं पहुँचता।
यहाँ यह और जुड़ जाता है कि पते पर जाया भी नहीं जाता, इसलिए वह लॉग भी नहीं बनता जो किसी और के सर्वर पर बनता। एक संदिग्ध URL की जाँच का पूरा मक़सद यही होता है कि वह जाँच किसी को दिखे नहीं, और यही एकमात्र वजह है कि यह पन्ना बिना किसी नेटवर्क क्रिया के बना है।
नहीं। वह तोड़ा जाता है, खोला नहीं जाता: न host को कोई रिक्वेस्ट, न पूर्वावलोकन, न redirect का हल। किसी संदिग्ध या एक बार इस्तेमाल होने वाली URL के साथ यही सबसे ज़रूरी बात है।
संभवतः पते में कोई @ है: https://[email protected]/ में उससे पहले की हर चीज़ credentials है और host dhokha.example है। यह मानक के अनुरूप है और एक बहुत पुरानी phishing तरकीब की बुनियाद है।
क्योंकि वह https का मानक port है और सामान्यीकरण उसे छोड़ देता है। https://udaharan.example:443/ और https://udaharan.example/ एक ही पता हैं — दो URL की शाब्दिक तुलना विफल होने की यह आम वजह है।
क्योंकि विनिर्देश किसी भी scheme को मानता है — mailto, tel, git+ssh, upi और सैकड़ों और। इसलिए htp वाक्य-विन्यास की दृष्टि से वैध scheme है। उसका वहाँ दिखना ही आपकी टाइपिंग की ग़लती का सुराग़ है।
नहीं। उपयोक्ता का नाम दिखता है और पासवर्ड में से सिर्फ़ यह संकेत कि वह मौजूद है। ये नतीजे अक्सर स्क्रीनशॉट और टिकट में पहुँच जाते हैं, और वहाँ उसका कोई काम नहीं।