सिक्योरिटी

    URL से संवेदनशील जानकारी क्यों लीक होती है, कैसे रोकें

    ब्राउज़र हिस्ट्री, सर्वर लॉग, CDN और Referer हेडर पूरे URL रखते हैं, HTTPS पर भी। लिंक कहां लीक होते हैं और ऐसे URL कैसे बनाएं जिनका लीक होना नुकसान न करे।

    W. Miller · अपडेट किया गया: · LinkPilot के बारे में

    URL निजी लगता है, क्योंकि वह सिर्फ़ उन्हीं लोगों के पास होना चाहिए जिन्हें आपने भेजा है। असल में URL वेब पर सबसे ज़्यादा लॉग होने वाले डेटा में से एक है: उसे ऐसे सिस्टम दर्ज करते हैं, कॉपी करते हैं और आगे भेजते हैं जिन्होंने आपसे कभी इजाज़त नहीं मांगी और जिनकी आप जांच नहीं कर सकते। नीचे ठीक-ठीक बताया गया है कि URL कहां लीक होता है और ऐसे लिंक कैसे बनाएं जो इसके बाद भी सुरक्षित रहें। इसी वजह से वन-टाइम सीक्रेट लिंक जनरेटर डिक्रिप्शन कुंजी को लिंक में # के बाद रखता है: वह हिस्सा कभी किसी सर्वर लॉग तक नहीं पहुंचता।

    URL कहां-कहां लीक होता है

    • ब्राउज़र हिस्ट्री। यूज़र जो भी URL खोलता है, वह डिवाइस पर सेव होता है और दूसरे डिवाइस पर सिंक हो सकता है, साथ ही ब्राउज़र कंपनी की सिंक सर्विस तक भी पहुंच सकता है।
    • HTTP सर्वर के access log। ज़्यादातर सर्वर डिफ़ॉल्ट रूप से पूरा request path और query string लॉग करते हैं। जिसके पास भी लॉग का एक्सेस है, उसके पास URL है।
    • रिवर्स प्रॉक्सी और CDN। Cloudflare, Fastly, आपका लोड बैलेंसर: ये सब URL लॉग करते हैं, और हर एक की अपनी रिटेंशन पॉलिसी होती है।
    • लॉग इकट्ठा करने वाली पाइपलाइन। access log शायद ही कभी एक मशीन पर रहते हैं। उन्हें सेंट्रल लॉगिंग और मॉनिटरिंग सर्विस में भेजा जाता है, जिससे URL रखने वाले सिस्टम की गिनती कई गुना बढ़ जाती है।
    • Referer हेडर। जब पेज किसी थर्ड-पार्टी रिसोर्स से जुड़ा होता है, तो ब्राउज़र सोर्स URL को Referer हेडर में भेज सकता है। एनालिटिक्स स्क्रिप्ट, एम्बेड किए गए वीडियो और ऐड पिक्सेल, सबको यह मिलता है।
    • ब्राउज़र एक्सटेंशन। जिन एक्सटेंशन के पास “read browsing history” की अनुमति है, वे हर URL देखते हैं, # के बाद वाले हिस्से समेत।
    • बुकमार्क सिंक। बुकमार्क किए गए URL यूज़र के सभी डिवाइस पर और ब्राउज़र कंपनी के सर्वर तक सिंक होते हैं।
    • लिंक प्रीव्यू बॉट। Slack, Teams, iMessage, LinkedIn और ईमेल ऐप प्रीव्यू दिखाने के लिए URL खोलते हैं, चुपचाप और मैसेज भेजते ही।
    • कंपनी की प्रॉक्सी और ईमेल गेटवे। कई संगठन अपनी सीमा से गुज़रने वाले हर URL की जांच करते हैं, उसे बदलते हैं और लॉग करते हैं।

    क्या HTTPS से URL निजी रहता है?

    नहीं। HTTPS सिर्फ़ रास्ते में URL को एन्क्रिप्ट करता है, इससे ज़्यादा कुछ नहीं। दोनों छोर पर URL फिर भी सेव होता है। इसे साफ़ समझना ज़रूरी है, क्योंकि “कनेक्शन एन्क्रिप्टेड है” को अक्सर “URL निजी है” समझ लिया जाता है।

    TLS रास्ते में path और query string को एन्क्रिप्ट करता है: ब्राउज़र और सर्वर के बीच नेटवर्क पर नज़र रखने वाला /reset?token=... नहीं पढ़ सकता। TLS क्या नहीं छिपाता: डेस्टिनेशन का होस्टनेम (आज ज़्यादातर कनेक्शन पर यह DNS रिज़ॉल्यूशन और TLS के SNI फ़ील्ड से दिखता है), और दोनों छोर पर मौजूद सब कुछ। ब्राउज़र फिर भी पूरा URL हिस्ट्री में दर्ज करता है, और सर्वर फिर भी उसे अपने access log में लिखता है। रास्ते का एन्क्रिप्शन बीच के नेटवर्क की हिफ़ाज़त करता है, दोनों छोर की नहीं, और URL लीक दोनों छोर पर ही होते हैं।

    एक उदाहरण: एक URL का सफ़र

    एक संवेदनशील URL को भेजने से लेकर क्लिक तक देखें, जैसे पासवर्ड रीसेट का लिंक https://example.com/reset?token=8f3a91...:

    1. मेल प्रोवाइडर मैसेज को (URL समेत) अनिश्चित समय तक सेव रखता है, और उसका सिक्योरिटी स्कैनर डिलीवरी के समय URL खोल सकता है।
    2. प्राप्तकर्ता का ईमेल गेटवे URL को बदलता है और लॉग करता है, फिर क्लिक के समय उसे दोबारा खोलता है।
    3. DNS example.com को रिज़ॉल्व करता है। अब होस्टनेम (path नहीं) रिज़ॉल्वर के लॉग में है।
    4. वेब सर्वर पूरी request line अपने access log में लिखता है। nginx/Apache के डिफ़ॉल्ट “combined” फ़ॉर्मेट में एंट्री ऐसी दिखती है:
    203.0.113.7 - - [14/Jul/2026:09:12:45 +0000]
      "GET /reset?token=8f3a91... HTTP/1.1" 200 5123 "-" "Mozilla/5.0 ..."
    
    1. सर्वर के आगे लगा CDN उसी URL को अपनी रिटेंशन के साथ लॉग करता है।
    2. पेज की एनालिटिक्स स्क्रिप्ट पेज का URL, query string समेत, किसी थर्ड-पार्टी सिस्टम में दर्ज करती है, जब तक उसे साफ़ तौर पर इसे हटाने के लिए सेट न किया गया हो।
    3. ब्राउज़र URL को हिस्ट्री में सेव करता है और सिंक करता है।

    एक बार भेजा, सात कॉपी बनीं, और वे कम से कम पांच संगठनों के पास हैं। इसमें किसी हमलावर की ज़रूरत नहीं पड़ी: वेब ठीक वैसे ही चला जैसे उसे बनाया गया है।

    Referer हेडर असल में कैसे काम करता है

    अगर आपका सीक्रेट दिखाने वाला पेज किसी भी बाहरी रिसोर्स से जुड़ा है (CDN का फ़ॉन्ट, एनालिटिक्स स्क्रिप्ट, एम्बेड की गई इमेज), तो ब्राउज़र पेज का URL Referer हेडर में उस ऑरिजिन को भेज सकता है।

    आज के ब्राउज़र डिफ़ॉल्ट रूप से strict-origin-when-cross-origin इस्तेमाल करते हैं (MDN: Referrer-Policy), जो दूसरे ऑरिजिन को भेजे जाने वाले referrer को सिर्फ़ ऑरिजिन तक छोटा कर देता है (पूरे path की जगह https://example.com/)। यह सच में सुधार है, लेकिन इस पर भरोसा नहीं करना चाहिए: उसी ऑरिजिन की request में पूरा URL अब भी जाता है, पेज की अपनी पॉलिसी डिफ़ॉल्ट को ढीला कर सकती है, और पुराने क्लाइंट और एम्बेड किए गए webview अलग-अलग तरह से बर्ताव करते हैं।

    बचाव के दो व्यावहारिक तरीके:

    <!-- Strip the referer for outbound requests on the page -->
    <meta name="referrer" content="no-referrer" />
    
    Referrer-Policy: no-referrer
    

    हेडर वाला तरीका पूरी साइट पर लागू होता है, meta टैग सिर्फ़ उस पेज पर। दोहरी सुरक्षा के लिए दोनों इस्तेमाल करें। इससे भी बेहतर यह है कि संवेदनशील पेज बिना किसी थर्ड-पार्टी रिसोर्स के दिखाएं, ताकि referrer भेजने के लिए कोई जगह ही न बचे।

    टोकन path में ज़्यादा सुरक्षित है, query string में या # के बाद?

    सिर्फ़ # के बाद का हिस्सा (fragment) request से बाहर रहता है, इसलिए सिर्फ़ वही सर्वर लॉग से बाहर रहता है। path और query string इस मामले में बराबर हैं। URL में टोकन कहां रखा है, इससे तय होता है कि उसे कौन देखता है:

    जगहसर्वर को भेजा जाता है?सर्वर लॉग में?Referer में?ब्राउज़र हिस्ट्री में?
    Path (/s/abc123)हांहांपॉलिसी पर निर्भरहां
    Query (?token=abc123)हांहांपॉलिसी पर निर्भरहां
    Fragment (#abc123)नहींनहींनहींहां

    fragment सच में अलग है: RFC 3986, सेक्शन 3.5 के मुताबिक उसे ब्राउज़र ही प्रोसेस करता है और वह HTTP request में कभी शामिल नहीं होता। इसी वजह से एंड-टू-एंड एन्क्रिप्टेड पेस्ट टूल डिक्रिप्शन कुंजी वहीं रखते हैं, क्योंकि सर्वर तक वह पहुंचती ही नहीं। फिर भी वह अदृश्य नहीं है: ब्राउज़र हिस्ट्री, एक्सटेंशन और पेज पर चल रही कोई भी JavaScript उसे पढ़ सकती है। path और query का फ़र्क नाम का है, निजता में कोई अंतर नहीं: दोनों एक ही लॉग में पहुंचते हैं।

    पासवर्ड रीसेट टोकन की समस्या

    URL में संवेदनशील टोकन रखना कमज़ोरी की एक जानी-मानी श्रेणी है। MITRE का CWE-598 (“Use of GET Request Method With Sensitive Query Strings”) ठीक इसी के बारे में है: query string में रखा संवेदनशील डेटा, रास्ते में एन्क्रिप्शन हो या न हो, लॉग, हिस्ट्री और referrer में पहुंच जाता है। इसी वजह से अच्छी तरह बने पासवर्ड रीसेट फ़्लो सिर्फ़ URL के गोपनीय रहने पर कभी भरोसा नहीं करते। वे टोकन को एक बार इस्तेमाल होने वाला, कम समय तक चलने वाला और अगले कदम से बंधा हुआ (नया पासवर्ड सेट करना) बनाते हैं, ताकि तीन हफ़्ते बाद किसी लॉग से मिला टोकन बेकार हो।

    यही आम सबक है: URL को लॉग से बाहर रखना आम तौर पर मुमकिन नहीं होता, लेकिन आप लॉग हुए URL को इतना बेकार बना सकते हैं कि जब तक कोई उसे पढ़े, उसका कोई काम न रहे।

    ऐसे URL बनाना जिनका लीक होना नुकसान न करे

    मान कर चलें कि आपका बनाया हर URL किसी न किसी दिन किसी अनचाही जगह दिखेगा, और उसे ऐसे बनाएं कि इससे फ़र्क न पड़े:

    • एक बार इस्तेमाल। पहली बार सफलतापूर्वक पढ़े जाने के बाद सीक्रेट मिटा दें, ताकि लीक हुआ URL किसी की हिस्ट्री में दिखने तक बेकार हो चुका हो।
    • छोटी एक्सपायरी। लीक होने की समय-सीमा को सीमित करें। पांच मिनट तक काम करने वाला URL एक हफ़्ते तक काम करने वाले URL से कहीं कम कीमती है।
    • अलग रास्ते से भेजा गया पासफ़्रेज़। ऐसा सीक्रेट मांगें जो कभी URL में नहीं था। तब अकेला URL, यानी लॉग के पास मौजूद इकलौती चीज़, काफ़ी नहीं रहता।
    • खोलने और दिखाने को अलग रखें। GET पर सिर्फ़ मेटाडेटा दें और असली डेटा सिर्फ़ साफ़ POST पर दें, ताकि प्रीव्यू बॉट और स्कैनर सीक्रेट को खोलकर खत्म न कर सकें।
    • संवेदनशील पेज पर कोई थर्ड-पार्टी रिसोर्स नहीं, साथ में Referrer-Policy: no-referrer और <meta name="robots" content="noindex">।
    • अपने लॉग में सीक्रेट वाले रूट छिपाएं। nginx में लॉग करने से पहले request URI को map करें (log_format के लिए ngx_http_log_module का रेफ़रेंस देखें):
    map $request_uri $loggable_uri {
        ~^/s/   "/s/[redacted]";
        default $request_uri;
    }
    log_format redacted '$remote_addr - $remote_user [$time_local] '
                        '"$request_method $loggable_uri" $status';
    access_log /var/log/nginx/access.log redacted;
    

    आपके हाथ में सिर्फ़ अपने लॉग हैं। CDN, प्रॉक्सी और ब्राउज़र की कॉपी बनी रहती हैं, और इसी वजह से इस सूची के पहले तीन तरीके सबसे ज़्यादा काम करते हैं।

    इसी खतरे की वजह से LinkPilot के सीक्रेट लिंक ऐसे काम करते हैं: URL को ऐसा माना जाता है जो लीक होगा ही, इसलिए अकेला URL कभी काफ़ी नहीं होता। GET सिर्फ़ मेटाडेटा लौटाता है। असली डेटा के लिए साफ़ POST से दिखाने की request चाहिए, और चाहें तो उस पर पासफ़्रेज़ लगाया जा सकता है, जिसे ब्राउज़र में ही SHA-256 से हैश किया जाता है। मिट चुके, एक्सपायर हो चुके या वापस लिए गए सीक्रेट HTTP 410 लौटाते हैं और उनका डेटा ऐसे ओवरराइट हो चुका होता है कि वापस नहीं आ सकता। दिखाने वाले response में Cache-Control: no-store होता है, और खुलने की घटनाओं में असली IP पता नहीं, बल्कि रोज़ बदलने वाले salt के साथ हैश किया गया IP लॉग होता है। और एक सीमा, जो हम खुलकर सिक्योरिटी आर्किटेक्चर पेज पर बताते हैं: डिक्रिप्शन कुंजी लिंक में # के बाद के हिस्से में रहती है, इसलिए पूरे लिंक को ही सीक्रेट मानना होगा। यह लेख ठीक इसी खतरे के बारे में है। लिंक लीक होने पर नुकसान को छोटी एक्सपायरी, पढ़ते ही मिट जाने वाला सीक्रेट और अलग रास्ते से भेजा गया पासफ़्रेज़ ही सीमित करते हैं।

    अपडेट, 29 सितंबर 2026: इस पैराग्राफ़ में पहले लिखा था कि LinkPilot एंड-टू-एंड एन्क्रिप्शन नहीं देता। अब यह टेक्स्ट वाला डेटा ब्राउज़र में ही एन्क्रिप्ट करता है, अटैचमेंट समेत।

    मुफ़्त में आज़माएं, साइन अप की ज़रूरत नहीं

    अपने आप मिटने वाला मैसेज

    ऐसा नोट भेजें जो एक बार पढ़ते ही मिट जाता है।

    टूल खोलें

    सीमाएं

    URL का डिज़ाइन हर चीज़ ठीक नहीं कर सकता। लिंक खोलने वाला व्यक्ति जायज़ तरीके से पढ़ने के बाद क्या करता है, इस पर URL के डिज़ाइन का कोई बस नहीं है। जो कॉपी थर्ड पार्टी के पास पहले से हैं, उन्हें यह मिटा नहीं सकता। और जिस URL में निजी डेटा खुलेआम लिखा है, उसे यह नहीं बचा सकता: अगर query string में किसी यूज़र का ईमेल पता है, तो कोई भी एक्सपायरी उसे लॉग से बाहर नहीं कर सकती। टिकाऊ नियम: URL में कभी ऐसा डेटा न रखें जिसे बाद में मिटाना पड़े, क्योंकि URL को हर उस जगह से मिटाना जहां उसकी कॉपी बनी है, व्यवहार में नामुमकिन है। इसकी जगह ऐसे URL बनाएं जो लीक होने पर बेकार हों।

    संदर्भ

    इस लेख के लिए टूल

    अक्सर पूछे जाने वाले सवाल

    LinkPilot ऐसा सीक्रेट लिंक भेजता है जो खुलने के बाद मिट जाता है।

    आपके ब्राउज़र में ही एन्क्रिप्ट होता है, एक बार दिखता है और फिर हमेशा के लिए मिट जाता है। अकाउंट बनाने की ज़रूरत नहीं।

    सीक्रेट लिंक बनाएं

    आगे पढ़ें

    सिक्योरिटी

    डेवलपर के लिए सुरक्षित लिंक शेयरिंग

    इंजीनियरिंग टीमों के लिए गाइड: वन-टाइम लिंक कब इस्तेमाल करें, उन्हें स्क्रिप्ट से कैसे बनाएं और ऑनबोर्डिंग व CI में कैसे जोड़ें।

    सिक्योरिटी

    सीक्रेट लिंक या पासवर्ड मैनेजर: किसका क्या काम

    पासवर्ड मैनेजर बार-बार इस्तेमाल होने वाले क्रेडेंशियल रखता है; वन-टाइम सीक्रेट लिंक एक व्यक्ति को एक बार क्रेडेंशियल देता है। ज़्यादातर टीमों को दोनों चाहिए।

    सिक्योरिटी

    लिंक स्कैनर और वन-टाइम सीक्रेट

    सादे GET पर मिटने वाला वन-टाइम लिंक Slack या ईमेल गेटवे के प्रीव्यू से ही खत्म हो जाता है। GET पर सिर्फ़ मेटाडेटा दें, “दिखाएं” क्लिक पर ही मिटाएं।