JWT क्या है? JSON Web Token समझें

JSON Web Token (JWT, उच्चारण "जॉट") एक कॉम्पैक्ट स्ट्रिंग है जो क्लेम का सेट — जैसे "यह यूज़र 42 है, admin रोल के साथ, 15:00 तक वैध" — और एक क्रिप्टोग्राफ़िक सिग्नेचर साथ लेकर चलती है, जिससे रिसीवर जाँच सकता है कि क्लेम किसी भरोसेमंद जारीकर्ता ने दिए हैं और उनमें बदलाव नहीं हुआ। JWT API ऑथेंटिकेशन, OAuth 2.0 एक्सेस टोकन और OpenID Connect ID टोकन का स्टैंडर्ड फ़ॉर्मेट है।

यह गाइड बताती है कि टोकन के अंदर क्या है, स्टैंडर्ड क्लेम का क्या मतलब है, टोकन डिकोड और वेरिफ़ाई कैसे करें, और वे सिक्योरिटी नियम जो सुरक्षित इम्प्लीमेंटेशन को ब्रीच से अलग करते हैं।

JWT के तीन हिस्से

JWT डॉट से अलग किए तीन Base64URL-एन्कोडेड सेगमेंट हैं: header.payload.signature। Base64URL यानी URL-सेफ़ कैरेक्टर वाला और बिना पैडिंग का Base64, ताकि टोकन हेडर, क्वेरी स्ट्रिंग और कुकी में जा सके।

  • हेडर — टोकन टाइप और साइनिंग एल्गोरिदम बताने वाला JSON, जैसे {"alg": "HS256", "typ": "JWT"}। इसमें kid (key id) भी हो सकता है जो वेरिफ़ायर को बताता है कौन-सी key इस्तेमाल करनी है।
  • पेलोड — JSON ऑब्जेक्ट के रूप में क्लेम। यहाँ कुछ भी रखा जा सकता है, लेकिन यह सिर्फ़ एन्कोडेड है, एन्क्रिप्टेड नहीं: जिसके पास टोकन है वह इसे पढ़ सकता है।
  • सिग्नेचर — हेडर में बताए एल्गोरिदम से एन्कोडेड हेडर और पेलोड पर कैलकुलेट किया जाता है। HS256 शेयर्ड सीक्रेट (HMAC) इस्तेमाल करता है; RS256 और ES256 साइन करने के लिए प्राइवेट key और वेरिफ़ाई करने के लिए पब्लिक key।
JWT के हेडर और पेलोड को कोई भी Base64URL-डिकोड कर सकता है; सिर्फ़ सिग्नेचर को, जो इन दो एन्कोडेड सेगमेंट पर कैलकुलेट होता है, जाँचने के लिए key चाहिए।

डॉट से अलग तीन Base64URL सेगमेंट: header.payload.signature

भाग 1:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.भाग 2:eyJzdWIiOiI0MiIsIm5hbWUiOiJMYXlsYSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTc1NjcwMDAwMCwiZXhwIjoxNzU2NzAzNjAwfQ
.भाग 3:4l3Y2cYpXqZ0cVZ5m4Q8n1fGx0y8s3oT0kq4rV7cWvA
  • 1–2कोई भी पढ़ सकता है: बिना key के JSON में डिकोड होते हैं। सिर्फ़ एन्कोडेड, एन्क्रिप्टेड नहीं।
  • 1–2साइन किया गया इनपुट: सिग्नेचर इन दो एन्कोडेड सेगमेंट पर कैलकुलेट होता है, इसलिए किसी एक को भी बदलने पर वेरिफ़िकेशन फ़ेल हो जाता है।
  • 3जाँचने के लिए key चाहिए: HS256 के लिए शेयर्ड सीक्रेट, RS256 और ES256 के लिए पब्लिक key।
  1. 1हेडरटोकन टाइप और साइनिंग एल्गोरिदम; इसमें kid (key id) भी हो सकता है।{"alg":"HS256","typ":"JWT"}एल्गोरिदम सर्वर पर पिन करें; यह हेडर तय न करे
  2. 2पेलोडस्टैंडर्ड क्लेम sub (subject), iat (issued at), exp (expiration); name और role कस्टम क्लेम हैं।{"sub":"42","name":"Layla","role":"admin","iat":1756700000,"exp":1756703600}exp − iat = 3600 सेकंड: एक घंटे के लिए वैध
  3. 3सिग्नेचरहेडर में बताए एल्गोरिदम से एन्कोडेड हेडर और पेलोड पर कैलकुलेट होता है: HS256 शेयर्ड सीक्रेट (HMAC) इस्तेमाल करता है।HMAC-SHA256(secret, "eyJhbGci…" + "." + "eyJzdWIi…")

पेज इस उदाहरण का सीक्रेट नहीं देता, इसलिए इसका सिग्नेचर जाँचा नहीं जा सकता; यह सिर्फ़ दिखाता है कि सिग्नेचर कहाँ होता है।

पाठ संस्करण
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiI0MiIsIm5hbWUiOiJMYXlsYSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTc1NjcwMDAwMCwiZXhwIjoxNzU2NzAzNjAwfQ
.4l3Y2cYpXqZ0cVZ5m4Q8n1fGx0y8s3oT0kq4rV7cWvA

header  → {"alg":"HS256","typ":"JWT"}
payload → {"sub":"42","name":"Layla","role":"admin","iat":1756700000,"exp":1756703600}

आज़माएँ: JWT डिकोडर

स्टैंडर्ड क्लेम और उनका मतलब

  • iss (issuer) — टोकन किसने बनाया, आमतौर पर ऑथ सर्वर का URL।
  • sub (subject) — टोकन किसके बारे में है, आमतौर पर यूज़र id।
  • aud (audience) — टोकन किस सर्विस के लिए है। वेरिफ़ायर को दूसरे audience के टोकन रिजेक्ट करने चाहिए।
  • exp (expiration) — Unix टाइमस्टैम्प जिसके बाद टोकन अमान्य है। छोटी लाइफ़टाइम (एक्सेस टोकन के लिए मिनट) लीक का नुक़सान सीमित करती है।
  • nbf (not before) और iat (issued at) — टाइमस्टैम्प जो बताते हैं टोकन कब वैध हुआ और कब बना।
  • jti (JWT id) — यूनिक id, replay पकड़ने या किसी खास टोकन को रद्द करने के लिए।
  • कस्टम क्लेम — रोल, परमिशन, tenant id, ईमेल। इन्हें छोटा रखें: टोकन हर रिक्वेस्ट के साथ जाता है।

आज़माएँ: JWT क्लेम एनालाइज़र आज़माएँ: JWT एक्सपायरेशन चेकर

डिकोड करना वेरिफ़ाई करना नहीं है

JWT डिकोड करने का मतलब है हेडर और पेलोड को Base64URL-डिकोड करके पढ़ना। यह कोई भी बिना किसी key के कर सकता है — इसीलिए डिकोड किए पेलोड पर अकेले कभी भरोसा नहीं करना चाहिए। वेरिफ़ाई करने का मतलब है सही key और एल्गोरिदम से सिग्नेचर दोबारा कैलकुलेट करके मिलान की पुष्टि करना, फिर exp, nbf, iss और aud जाँचना।

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

आज़माएँ: JWT डिकोडर आज़माएँ: JWT हेडर एनालाइज़र

HS256 बनाम RS256 बनाम ES256

  • HS256 (SHA-256 के साथ HMAC) — एक शेयर्ड सीक्रेट साइन भी करता है और वेरिफ़ाई भी। सरल, तेज़, तब ठीक जब एक ही सर्विस टोकन जारी और इस्तेमाल करती है। जो पक्ष वेरिफ़ाई कर सकता है वह जाली टोकन भी बना सकता है।
  • RS256 (RSA सिग्नेचर) — प्राइवेट key साइन करती है, पब्लिक key वेरिफ़ाई करती है। कोई भी सर्विस प्रकाशित पब्लिक key (अक्सर JWKS एंडपॉइंट से) से वेरिफ़ाई कर सकती है, टोकन बनाए बिना। OAuth प्रोवाइडर का डिफ़ॉल्ट।
  • ES256 (P-256 के साथ ECDSA) — RS256 जैसा असममित मॉडल, कहीं छोटी key और सिग्नेचर के साथ।
  • none — ऐसा एल्गोरिदम जिसका मतलब है "कोई सिग्नेचर नहीं"। वेरिफ़ायर को इसे रिजेक्ट करना चाहिए; alg=none स्वीकार करना क्लासिक JWT कमज़ोरियों में से एक है।

आज़माएँ: JWT जनरेटर आज़माएँ: HMAC जनरेटर

JWT सिक्योरिटी नियम

  • सिग्नेचर वेरिफ़ाई करें और सर्वर पर एल्गोरिदम पिन करें। टोकन के अपने हेडर को कभी तय न करने दें कि कौन-सा एल्गोरिदम इस्तेमाल होगा।
  • हमेशा exp जाँचें, और aud व iss को अपनी वैल्यू से मिलाएँ।
  • पेलोड में कभी सीक्रेट, पासवर्ड या संवेदनशील निजी डेटा न रखें — टोकन रखने वाला कोई भी उसे पढ़ सकता है। एन्क्रिप्शन चाहिए तो JWE इस्तेमाल करें।
  • एक्सेस टोकन छोटी लाइफ़ के रखें और नए पाने के लिए रिफ़्रेश टोकन इस्तेमाल करें।
  • ब्राउज़र में टोकन सावधानी से स्टोर करें: HttpOnly, Secure, SameSite कुकी localStorage से सुरक्षित है, जिसे कोई भी इंजेक्ट की गई स्क्रिप्ट पढ़ सकती है।
  • HS256 के लिए मज़बूत सीक्रेट इस्तेमाल करें — कम से कम 256 बिट रैंडमनेस, कभी पासवर्ड नहीं।
  • रद्द करने की योजना बनाएँ: JWT एक्सपायर होने तक वैध रहता है, इसलिए लॉगआउट या समझौता हुए अकाउंट के लिए denylist (jti) या छोटी लाइफ़टाइम चाहिए।

आज़माएँ: रैंडम सीक्रेट जनरेटर आज़माएँ: OAuth टोकन डिकोडर

OAuth 2.0 और OpenID Connect में JWT

OAuth 2.0 एक्सेस टोकन अक्सर JWT होते हैं, हालाँकि स्पेक इसे ज़रूरी नहीं करता; OpenID Connect ID टोकन हमेशा JWT होते हैं। ID टोकन क्लाइंट एप्लिकेशन के लिए ऑथेंटिकेटेड यूज़र (sub, ईमेल, नाम) बताता है; एक्सेस टोकन क्लाइंट को API कॉल करने की परमिशन देता है (scope, aud)। दोनों एक ही तरह वेरिफ़ाई होते हैं, लेकिन ID टोकन को कभी एक्सेस टोकन की तरह API को नहीं भेजना चाहिए।

आज़माएँ: OAuth टोकन डिकोडर

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

क्या JWT एन्क्रिप्टेड होता है?

नहीं — स्टैंडर्ड साइन्ड JWT (JWS) सिर्फ़ Base64URL-एन्कोडेड होता है। इसका पेलोड टोकन रखने वाला कोई भी पढ़ सकता है। एन्क्रिप्टेड टोकन (JWE) मौजूद हैं लेकिन बहुत कम आम हैं।

क्या JWT को सीक्रेट के बिना डिकोड किया जा सकता है?

हाँ। हेडर और पेलोड सादा Base64URL हैं, इसलिए कोई भी डिकोडर उन्हें पढ़ सकता है। सीक्रेट या key सिर्फ़ सिग्नेचर वेरिफ़ाई करने के लिए चाहिए, जो टोकन के असली होने का सबूत है।

कैसे जाँचें कि JWT एक्सपायर हो गया है?

इसे डिकोड करें और exp क्लेम (सेकंड में Unix टाइमस्टैम्प) की तुलना मौजूदा समय से करें। वेरिफ़ायर लाइब्रेरी यह अपने आप करती है; ऑनलाइन डिकोडर एक्सपायरी को पढ़ने योग्य तारीख़ के रूप में दिखाता है।

JWT और सेशन कुकी में क्या फ़र्क़ है?

सेशन कुकी एक अपारदर्शी id है जिसे सर्वर अपने स्टोर में देखता है; JWT सेशन डेटा खुद साइन करके साथ रखता है, इसलिए सर्वर को लुकअप नहीं चाहिए। JWT सर्विसेज़ के बीच आसानी से स्केल होते हैं; सेशन रद्द करना आसान है।

वेब ऐप में JWT कहाँ स्टोर करें?

SameSite सेट के साथ HttpOnly, Secure कुकी बेहतर है, ताकि पेज पर JavaScript उसे न पढ़ सके। localStorage सुविधाजनक है लेकिन किसी भी cross-site scripting बग से टोकन एक्सपोज़ कर देता है।

क्या JWT को ऑनलाइन डिकोडर में पेस्ट करना सुरक्षित है?

सिर्फ़ तब जब डिकोडर पूरी तरह आपके ब्राउज़र में चले और टोकन कहीं न भेजे। Mutqan का JWT डिकोडर लोकली काम करता है; फिर भी प्रोडक्शन टोकन को सीक्रेट मानें और जहाँ हो सके टेस्ट टोकन इस्तेमाल करें।

संदर्भ

  • RFC 7519: JSON Web Token (JWT)IETF · 2015JWT फ़ॉर्मेट — हेडर, पेलोड, सिग्नेचर — और रजिस्टर्ड क्लेम iss, sub, aud, exp, nbf, iat और jti को परिभाषित करता है।
  • RFC 7515: JSON Web Signature (JWS)IETF · 2015JWT कैसे साइन और सीरियलाइज़ होता है: प्रोटेक्टेड हेडर, साइनिंग इनपुट और कॉम्पैक्ट सीरियलाइज़ेशन।
  • RFC 8725: JSON Web Token Best Current PracticesIETF · 2020JWT इम्प्लीमेंटेशन के सुरक्षा नियम: alg=none अस्वीकार करें, एल्गोरिद्म पिन करें, iss/aud जाँचें, छोटी अवधि रखें।
  • OWASP Cheat Sheet Series: JSON Web TokenOWASP Foundationव्यावहारिक JWT हार्डनिंग: एल्गोरिद्म कन्फ़्यूज़न, टोकन साइडजैकिंग, ब्राउज़र में स्टोरेज, रिवोकेशन।

अभ्यास

बैंकिंग ऐप के एक्सेस टोकन और उसके वेरिफ़िकेशन टेस्ट की समीक्षा

आपका काम

आप एक retail bank (काल्पनिक) के online banking web app और उसके इस्तेमाल किए Accounts API को टेस्ट करते हैं। Build 4.2.0 staging environment पर है। नीचे के material में टीम का टोकन specification है, जो test basis है (T1–T7); एक एक्सेस टोकन जो आपने test customer के रूप में sign in करने के बाद ब्राउज़र से कॉपी किया; आठ वेरिफ़िकेशन टेस्ट के नतीजे जो एक साथी ने Accounts API पर चलाए; और front-end developer का एक सवाल।

टोकन डिकोड करें, उसे specification से मिलाएँ, हर टेस्ट के नतीजे को परखें, और developer को जवाब दें। लगभग 30 मिनट रखें। JWT Decoder हेडर और पेलोड दिखाता है, और iat, nbf व exp को UTC तारीख़ों के रूप में भी दिखाता है (टोकन की सिर्फ़ सात लाइनें कॉपी करें; line breaks अनदेखे हो जाते हैं)। अपनी राय बना लेने के बाद JWT Claims Analyzer और JWT Header Analyzer जोखिम भरे क्लेम और हेडर वैल्यू दिखाते हैं; पर वे आम practice के हिसाब से परखते हैं, T1–T7 के हिसाब से नहीं, इसलिए वे ऐसी चीज़ भी स्वीकार कर सकते हैं जिसे specification मना करता है। अगर आप कागज़ पर काम कर रहे हैं, तो डिकोड किया टोकन model answer के पहले paragraph में है।

V2 और V3 की तरह टोकन बदलना ऐसा टेस्ट है जो आप सिर्फ़ अपनी टीम के सिस्टम पर, या सिस्टम के मालिक की लिखित अनुमति से चलाते हैं।

सामग्री
एक retail bank (काल्पनिक) की online banking - web app और Accounts API
Build 4.2.0 staging पर। Accounts API: https://api.staging.bank.example/v1/accounts

टोकन specification (test basis)
  T1  ऑथ सर्वर एक्सेस टोकन ES256 से साइन करता है। Accounts API सिर्फ़ ES256 स्वीकार
      करता है और पब्लिक key ऑथ सर्वर के JWKS से kid के आधार पर लेता है।
  T2  iss का मान https://auth.staging.bank.example और aud का मान accounts-api हो।
  T3  एक्सेस टोकन की लाइफ़टाइम 10 मिनट है (exp = iat + 600); web app उसे
      रिफ़्रेश टोकन से renew करता है।
  T4  एक्सेस टोकन में सिर्फ़ iss, sub (customer number), aud, iat, nbf, exp, jti
      और scope होते हैं। कोई निजी डेटा नहीं।
  T5  Sign out करने पर टोकन का jti एक denylist में जाता है जिसे API जाँचता है।
  T6  Web app एक्सेस टोकन HttpOnly, Secure, SameSite कुकी में रखता है,
      localStorage में कभी नहीं।
  T7  जो टोकन वेरिफ़िकेशन में फ़ेल हो, API उसका जवाब 401 से देता है।

Test customer C-100482 का एक्सेस टोकन, 30 सितंबर 2026 को sign-in के तुरंत बाद
ब्राउज़र के localStorage (key: access_token) से कॉपी किया गया:
  eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InN0Zy0yMDI2LTA5In0.eyJpc3MiOiJodHRwczov
  L2F1dGguc3RhZ2luZy5iYW5rLmV4YW1wbGUiLCJzdWIiOiJDLTEwMDQ4MiIsImF1ZCI6ImFjY291bnRzLWFw
  aSIsImlhdCI6MTc5MDc0ODAwMCwibmJmIjoxNzkwNzQ4MDAwLCJleHAiOjE3OTA4MzQ0MDAsImp0aSI6Ijdk
  MmYwYzllLTRiMWEtNGU4ZS05YTNkLTVjNmIyZjFlOGE0MCIsInNjb3BlIjoiYWNjb3VudHM6cmVhZCB0cmFu
  c2ZlcnM6d3JpdGUiLCJyb2xlIjoiY3VzdG9tZXIiLCJuYW1lIjoiU2FyYSBBbC1IYXJiaSIsIm5hdGlvbmFs
  X2lkIjoiMTIzNDU2Nzg5MCJ9._rh027IPcSrasUBWj1c2UiLI8IbEc7oMm7nIwMXaSc7Mt0yf3TWbGdoASKU
  OItR_TDURrtVHr0XfGXNLMb9u-A

GET /v1/accounts पर वेरिफ़िकेशन टेस्ट, एक साथी ने staging पर चलाए
  V1  कॉपी किया टोकन, बिना बदलाव, उसकी लाइफ़टाइम के भीतर
      -> 200 OK   C-100482 के accounts
  V2  पेलोड बदला: sub को C-100483 किया; हेडर और सिग्नेचर वही
      -> 401 Unauthorized
  V3  हेडर को {"alg":"none","typ":"JWT"} किया, sub को C-100483 किया,
      सिग्नेचर हटाया (टोकन डॉट पर ख़त्म होता है)
      -> 200 OK   C-100483 के accounts
  V4  ऐसा टोकन जिसका exp 40 सेकंड पहले बीत चुका था
      -> 200 OK   C-100482 के accounts
  V5  ऐसा टोकन जिसका exp 15 मिनट पहले बीत चुका था
      -> 401 Unauthorized
  V6  ऑथ सर्वर का Cards API के लिए जारी किया एक्सेस टोकन (aud: cards-api)
      -> 200 OK   C-100482 के accounts
  V7  Web app का OpenID Connect ID टोकन (aud: web-banking-app; इसमें name और
      email हैं, scope नहीं)
      -> 200 OK   C-100482 के accounts
  V8  कॉपी किया टोकन, ग्राहक के sign out करने के बाद दोबारा भेजा
      -> 401 Unauthorized

Front-end developer का सवाल
  "पेज के हेडर में ग्राहक का नाम दिखता है, और जब scope में transfers:write न हो
   तो हम Transfers मेन्यू छिपा देते हैं। दोनों हम JavaScript में एक्सेस टोकन से
   पढ़ते हैं। क्या name और national_id टोकन में रह सकते हैं?"
चरण
  1. टोकन डिकोड करें और iat, nbf और exp को UTC तारीख़ों के रूप में लिखें। 1 अक्टूबर 2026 को 06:00 UTC से decoder टोकन को expired दिखाता है; आज का status नहीं, उसकी लाइफ़टाइम परखें।
  2. हेडर, हर क्लेम और टोकन जहाँ स्टोर था उस जगह को T1–T7 से मिलाएँ। हर item को सही, defect या टीम के लिए सवाल चिह्नित करें, और वह नियम लिखें जो टूटा है।
  3. V1–V8 के लिए असली नतीजा पढ़ने से पहले specification से expected result लिखें। फिर हर row को सही, defect या सवाल चिह्नित करें, और एक ही root cause वाले defects को साथ रखें।
  4. कम से कम तीन ऐसे वेरिफ़िकेशन टेस्ट लिखें जो log में अभी नहीं हैं।
  5. Developer के सवाल का जवाब दें।
  6. वह finding चुनें जिसे आप सबसे पहले रिपोर्ट करेंगे, उसकी defect report का title लिखें और प्राथमिकता का कारण बताएँ।
मॉडल उत्तर दिखाएँ
मॉडल उत्तर

डिकोड किया टोकन। हेडर: {"alg":"ES256","typ":"JWT","kid":"stg-2026-09"}। पेलोड: iss https://auth.staging.bank.example, sub C-100482, aud accounts-api, iat और nbf दोनों 1790748000 (30 सितंबर 2026, 06:00:00 UTC), exp 1790834400 (1 अक्टूबर 2026, 06:00:00 UTC), jti 7d2f0c9e-4b1a-4e8e-9a3d-5c6b2f1e8a40, scope accounts:read transfers:write, role customer, name Sara Al-Harbi, national_id 1234567890। सिग्नेचर सेगमेंट 86 कैरेक्टर का है, यानी 64 bytes, जो ES256 सिग्नेचर का साइज़ है।

सार: पाँच defects (लाइफ़टाइम, निजी डेटा, स्टोरेज, V3 में none एल्गोरिदम, और V6 व V7 में audience की जाँच न होना), टीम के लिए तीन सवाल (role, V4 का leeway, और V7 से उठा सवाल कि क्या API scope जाँचता है), और चार rows जिनमें API सही व्यवहार करता है (V1, V2, V5, V8)। डिकोड करने के लिए कोई key नहीं चाहिए थी, और यही गाइड की मुख्य बात है: पेलोड में जो कुछ है, टोकन रखने वाला हर व्यक्ति उसे पढ़ सकता है।

हेडर, iss, aud, sub, jti और scope — सही। alg ES256 है और साथ में kid है, जैसा T1 माँगता है, और iss व aud T2 से मेल खाते हैं। nbf का iat के बराबर होना सामान्य है: टोकन जारी होने के पल से वैध है। jti ही T5 की denylist को मुमकिन बनाता है।

लाइफ़टाइम — defect (T3)। exp - iat 86400 सेकंड है, यानी 600 सेकंड (10 मिनट) की जगह 24 घंटे, इसलिए लीक हुआ टोकन कुछ मिनटों की जगह पूरे दिन इस्तेमाल हो सकता है। कोई आम claims analyzer 24 घंटे की लाइफ़टाइम को ठीक बता सकता है; पर यहाँ test basis T3 है, और T3 10 मिनट कहता है। Severity: Major। Expected result: exp = iat + 600। Fix के बाद यह भी जाँचें कि टोकन अपने 10 मिनट (और V4 वाले leeway) के थोड़ी देर बाद रिजेक्ट होता है, और web app ग्राहक को sign out किए बिना रिफ़्रेश टोकन से उसे renew करता है।

name और national_id — defect (T4)। पेलोड सिर्फ़ एन्कोडेड है, एन्क्रिप्टेड नहीं: आपने अभी बिना किसी key के एक national ID पढ़ ली, और ब्राउज़र स्टोरेज, किसी log, proxy या bug report के साथ लगे screenshot में टोकन देखने वाला कोई भी यही कर सकता है। टोकन हर रिक्वेस्ट के साथ भी जाता है। Severity: Major; बैंक के data protection नियम इसे और ऊँचा कर सकते हैं। Expected result: पेलोड में सिर्फ़ T4 में लिखे क्लेम हों। यह नियम एक्सेस टोकन का है; ID टोकन web app के लिए है और उसमें नाम हो सकता है (developer का सवाल देखें)।

role — टीम के लिए सवाल। T4 में यह नहीं है, इसलिए या तो specification पुराना है या यह क्लेम हटना चाहिए। साइन्ड टोकन में रोल अपने आप में सिक्योरिटी समस्या नहीं है, क्योंकि सिग्नेचर उसकी रक्षा करता है, लेकिन सिर्फ़ तब जब API पिन किए गए एल्गोरिदम से सिग्नेचर वेरिफ़ाई करे, और V3 दिखाता है कि आज ऐसा नहीं है: none के साथ कोई भी कोई भी रोल लिख सकता है।

स्टोरेज — defect (T6)। टोकन localStorage में access_token key के नीचे है, जहाँ पेज पर चलने वाली कोई भी स्क्रिप्ट उसे पढ़ सकती है, cross-site scripting (XSS) बग से इंजेक्ट की गई स्क्रिप्ट भी। 24 घंटे की लाइफ़टाइम के साथ चोरी हुआ टोकन पूरे दिन काम करता रहता है, जब तक ग्राहक sign out न करे (V8 दिखाता है कि sign out उसे सच में रद्द करता है)। Severity: Major। Expected result: HttpOnly, Secure, SameSite कुकी। Fix आने पर उसका Set-Cookie हेडर Cookie Analyzer में पेस्ट करके तीनों attributes की पुष्टि करें, और जाँचें कि localStorage में अब टोकन नहीं है।

V1 — सही: ग्राहक के अपने accounts के साथ 200। V2 — सही: 401। पेलोड बदलने से सिग्नेचर टूट जाता है, और API इसे पकड़ लेता है। डिकोड और वेरिफ़ाई में यही फ़र्क़ है: डिकोड किया पेलोड कोई भी बदल सकता है, लेकिन उससे मेल खाता सिग्नेचर सिर्फ़ ऑथ सर्वर की प्राइवेट key बना सकती है।

V3 — defect, Critical (T1, T7)। Expected result: 401, क्योंकि T1 सिर्फ़ ES256 की अनुमति देता है। ग्राहक C-100483 के accounts के साथ 200 failure है; उसके पीछे का defect यह है कि API टोकन के अपने हेडर को एल्गोरिदम चुनने देता है, और none पर कोई सिग्नेचर जाँचता ही नहीं। V2 के साथ देखें तो साफ़ है कि हेडर ES256 कहे तो वेरिफ़िकेशन चलता है, और हेडर माँगे तो बंद हो जाता है। जो भी किसी ग्राहक का नंबर जानता है या अनुमान लगा लेता है, वह उसके accounts पढ़ सकता है, और कोई भी दूसरा क्लेम भी लिख सकता है, जैसे transfers:write वाला scope।

V4 — सवाल। RFC 7519 वेरिफ़ायर को सर्वरों की घड़ियों के फ़र्क़ के लिए छोटा leeway देने की अनुमति देता है, आमतौर पर कुछ मिनट से ज़्यादा नहीं, और T3 इस बारे में कुछ नहीं कहता। V5 दिखाता है कि exp जाँचा जाता है, इसलिए leeway कहीं 40 सेकंड और 15 मिनट के बीच है। टीम से configured value पूछें और उसे specification में जुड़वाएँ; फिर दो values से boundary टेस्ट करें: leeway के ठीक भीतर इस्तेमाल हुआ टोकन स्वीकार हो, और उसके ख़त्म होने के एक सेकंड बाद इस्तेमाल हुए टोकन पर 401 आए। अगर leeway कुछ मिनट से लंबा निकले तो उसे defect के रूप में रिपोर्ट करें, क्योंकि वह हर टोकन की उम्र बढ़ा देता है। V5 — सही: 401।

V6 — defect (T2)। Expected result: 401, क्योंकि aud cards-api है, accounts-api नहीं। एक सर्विस के लिए जारी टोकन दूसरी सर्विस खोल देता है, इसलिए Cards API से, या ऐसे टोकन पाने वाली किसी भी सर्विस से लीक हुआ टोकन ग्राहकों के accounts भी खोल देता है। V7 — उसी root cause वाला defect: ID टोकन web app के लिए है, API के लिए नहीं, और गाइड कहती है कि उसे कभी एक्सेस टोकन की तरह इस्तेमाल नहीं करना चाहिए। V6 और V7 को एक ही defect के रूप में रिपोर्ट करें, "Accounts API aud नहीं जाँचता", और दोनों rows उदाहरण के रूप में दें; दो अलग reports एक ही root cause को दो बार बताएँगी। Severity: Major (कुछ टीमें इसे Critical मानती हैं)। V7 एक सवाल भी उठाता है: ID टोकन में scope है ही नहीं, फिर भी accounts की list मिल गई, इसलिए पूछें कि क्या API accounts:read जाँचता है, और इसके लिए एक टेस्ट जोड़ें।

V8 — सही: sign out के बाद 401, यानी T5 की jti denylist काम करती है। पर इससे 24 घंटे की लाइफ़टाइम बेनुक़सान नहीं हो जाती: जो ग्राहक कभी sign out नहीं करता, उसका टोकन पूरे दिन वैध रहता है।

वे वेरिफ़िकेशन टेस्ट जो log में अभी नहीं हैं (कोई भी तीन काफ़ी हैं): हेडर को HS256 करके अपनी पसंद के HMAC सीक्रेट से साइन किया टोकन, जैसे JWT Generator से, expected 401, और API के log में दिखना चाहिए कि उसे एल्गोरिदम की वजह से रिजेक्ट किया गया, क्योंकि एल्गोरिदम सर्वर चुनता है, हेडर नहीं; fix के बाद अलग letter case में none, जैसे None और NONE, क्योंकि जो जाँच सिर्फ़ ठीक none string को ब्लॉक करती है वह इन्हें छोड़ सकती है; ऑथ सर्वर की जगह आपकी अपनी ES256 key से साइन किया टोकन, expected 401, क्योंकि भरोसा सिर्फ़ JWKS की keys पर होना चाहिए; development environment के ऑथ सर्वर का टोकन (दूसरा iss और दूसरी key) और ऐसा टोकन जिसका nbf भविष्य में हो, दोनों पर expected 401; ऐसा एक्सेस टोकन जिसके scope में accounts:read न हो, expected: रिक्वेस्ट रिजेक्ट हो (RFC 6750 अपर्याप्त scope पर 403 की सलाह देता है; कोड टीम से पक्का करें); और V4 वाली leeway boundary। चुने हुए क्लेम और वैध ES256 सिग्नेचर वाले टोकन के लिए staging पर ऑथ टीम की मदद चाहिए, जैसे ऐसा test client जो उन्हें जारी करे; ये टेस्ट छोड़ने की जगह वह मदद माँगें।

Developer का सवाल: national_id के लिए नहीं, और name के लिए इस रूप में नहीं। निजी डेटा एक्सेस टोकन में नहीं होना चाहिए (T4)। Web app के लिए बना टोकन ID टोकन है, और उसमें ग्राहक का नाम पहले से है (V7 देखें), इसलिए पेज नाम ID टोकन से या ग्राहक की profile और permissions लौटाने वाले endpoint से दिखा सकता है; national_id किसी भी टोकन में नहीं होना चाहिए। साथ ही, JavaScript में एक्सेस टोकन पढ़ना सिर्फ़ इसलिए चलता है कि टोकन localStorage में है: T6 के मुताबिक़ HttpOnly कुकी में जाते ही पेज की स्क्रिप्ट उसे पढ़ ही नहीं पाएँगी, इसलिए design तो बदलना ही होगा। Transfers मेन्यू छिपाना सुविधा के रूप में ठीक है, पर यह सिक्योरिटी कंट्रोल नहीं है: डिकोड करना वेरिफ़ाई करना नहीं है, इसलिए API को हर transfer रिक्वेस्ट पर transfers:write ख़ुद जाँचना चाहिए। इसका टेस्ट जोड़ें: जिस टोकन के scope में transfers:write न हो, उससे की गई transfer रिक्वेस्ट रिजेक्ट होनी चाहिए।

सबसे पहले V3 रिपोर्ट करें। Title का उदाहरण: "Accounts API alg: none वाले बिना सिग्नेचर के टोकन स्वीकार करता है; sub बदलने पर दूसरे ग्राहक के accounts दिखते हैं"। यह पहले इसलिए है कि इसके लिए न चोरी हुआ टोकन चाहिए न key, सिर्फ़ एक customer number, और यह हर ग्राहक के accounts खोल देता है: severity Critical, प्राथमिकता सबसे ऊँची। सिक्योरिटी defect होने के कारण developers को तुरंत बताएँ और सिक्योरिटी मामलों के लिए अपनी टीम की प्रक्रिया अपनाएँ, जैसे restricted access वाला ticket। फिर audience वाला defect (V6 और V7); फिर 24 घंटे की लाइफ़टाइम और localStorage में स्टोरेज, जो मिलकर तय करते हैं कि चोरी हुआ टोकन कितनी देर और कितनी आसानी से इस्तेमाल हो सकता है; फिर पेलोड का निजी डेटा। अगर आपकी टीम national ID को पहले रखती है क्योंकि बैंक के data protection नियम इसे incident मानते हैं, तो यह ठीक कारण है; अहम यह है कि प्राथमिकता असर के हिसाब से तय हो। हर fix के बाद संबंधित rows confirmation testing के रूप में दोबारा चलाएँ, और V1, V2, V5 और V8 regression tests के रूप में, क्योंकि वेरिफ़िकेशन code में बदलाव आज काम कर रही चीज़ों को तोड़ सकता है।

अपना काम जाँचने के लिए: आपके पास पाँच defects होने चाहिए, और V1, V2, V5 या V8 में कोई defect नहीं। अगर आपने V2 को defect माना, तो गाइड का "डिकोड करना वेरिफ़ाई करना नहीं है" section फिर पढ़ें: बदले हुए पेलोड पर 401 ठीक वही है जो वेरिफ़ायर को करना चाहिए। अगर आपने nbf के iat के बराबर होने को समस्या माना, तो क्लेम वाला section फिर पढ़ें: nbf सिर्फ़ यह तय करता है कि टोकन कब से वैध है।

इस topic में आपकी प्रगति

QA रोडमैप का हिस्सा

इस गाइड में बताए गए टूल्स

JWT का हेडर और पेलोड डिकोड करें, क्लेम जाँचें और एक्सपायरी देखें — पूरी तरह आपके ब्राउज़र में।

सुरक्षा

टेस्टिंग के लिए कस्टम क्लेम से साइन किए हुए JWT (HS256 / HS384 / HS512) बनाएँ।

सुरक्षा

JWT क्लेम में गायब, जोखिम भरी या ग़ैर-मानक वैल्यू जाँचें और सुरक्षा संबंधी सुझाव पाएँ।

सुरक्षा

जाँचें कि कोई JWT एक्सपायर हो चुका है, अभी वैध नहीं है, या एक्सपायरी में कितना समय बचा है।

सुरक्षा

JWT का JOSE हेडर जाँचें: alg, typ, kid, jku, x5u और एल्गोरिदम-कन्फ़्यूज़न के संभावित जोखिम।

सुरक्षा

OAuth 2.0 / OpenID Connect एक्सेस और ID टोकन डिकोड करें और स्कोप, audience तथा लाइफ़टाइम समझें।

सुरक्षा

वेबहुक और API रिक्वेस्ट साइनिंग के लिए HMAC सिग्नेचर (SHA-256/384/512/SHA-1) बनाएँ।

सुरक्षा

Base64 या Base64url स्ट्रिंग को टेक्स्ट में डिकोड करें, पैडिंग अपने आप ठीक होने के साथ।

एन्कोडिंग

Mutqan Soft कैसे मदद कर सकता है

और गाइड

और गाइड
एन्कोडिंग

Base64 क्या है? एन्कोडिंग समझें

Base64 समझें: यह क्या है और क्या नहीं, एन्कोडिंग कैसे काम करती है, आउटपुट एक-तिहाई क्यों बढ़ता है, Base64 बनाम Base64URL, = पैडिंग, और एन्कोड-डिकोड।

5 मिनट पढ़ने का समय
परफ़ॉर्मेंस

परफ़ॉर्मेंस और सुरक्षा रेज़िलिएंस टेस्टिंग

उत्पाद को लोड, विफलता और हमले के लिए कैसे टेस्ट करें: असली लक्ष्यों के साथ लोड, स्ट्रेस और सोक टेस्ट, फ़ेल्योर इंजेक्शन, OWASP बेसलाइन और क्या दर्ज करें।

10 मिनट पढ़ने का समय
API टेस्टिंग

API टेस्टिंग क्या है? REST API कैसे टेस्ट करें

API टेस्टिंग समझें: यह क्या है, हर रिक्वेस्ट और रिस्पॉन्स में क्या जाँचें, REST API टेस्ट करने का स्टेप-बाय-स्टेप तरीका, आम गलतियाँ और मुफ़्त टूल्स।

7 मिनट पढ़ने का समय
JSON और डेटा

JSON क्या है?

JSON आसान भाषा में: यह क्या है, छह वैल्यू टाइप, वे सिंटैक्स नियम जिनमें लोग अटकते हैं, इसे फ़ॉर्मेट और वैलिडेट कैसे करें, और XML व YAML से इसकी तुलना।

5 मिनट पढ़ने का समय
यूटिलिटीज़

UUID क्या है? v4 बनाम v7, UUID बनाम GUID और ULID

UUID समझें: 128-बिट फ़ॉर्मेट, v4 बनाम v7, डेटाबेस key के लिए v7 बेहतर क्यों, UUID बनाम GUID बनाम ULID, कॉलिज़न की संभावना, और जनरेट-वैलिडेट कैसे करें।

5 मिनट पढ़ने का समय
वेब

HTTP स्टेटस कोड समझें

HTTP स्टेटस कोड की हर क्लास उन कोड के साथ जो असल में मिलते हैं — 200, 301, 400, 401, 403, 404, 422, 429, 500, 502, 503, 504 — वजह और कौन-सा लौटाएँ।

5 मिनट पढ़ने का समय