TrendVidStream ਨੇ ਆਪਣਾ ਸਾਰਾ authentication stack ਇੱਕ rotating-refresh-token ਸਿਸਟਮ ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ ਹੈ ਜੋ ਚੋਰੀ ਕੀਤੇ ਗਏ ਟੋਕਨ ਨੂੰ ਉਸੇ ਪਲ ਫੜ ਲੈਂਦਾ ਹੈ ਜਦੋਂ ਉਸਦੀ ਦੁਬਾਰਾ ਵਰਤੋਂ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਇਸ ਬਦਲਾਅ ਨੇ 30-ਦਿਨਾਂ ਵਾਲੇ JWT ਨੂੰ, ਜੋ ਪਹਿਲਾਂ ਇੱਕ ਹਕਰ (attacker) ਨੂੰ ਖੁੱਲ੍ਹ ਕੇ ਘੁੰਮਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਸੀ, ਇੱਕ ਅਜਿਹੇ ਘੱਟ ਸਮੇਂ ਵਾਲੇ credential ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ ਹੈ ਜੋ ਤੁਰੰਤ lock-out ਨੂੰ ਟ੍ਰਿਗਰ ਕਰ ਦਿੰਦਾ ਹੈ।

ਇੱਕ ਇਕਲੌਤੀ breach ਨੇ ਇਸ ਬਦਲਾਅ ਲਈ ਮਜਬੂਰ ਕੀਤਾ: ਇੱਕ partner SDK ਨੇ 30-ਦਿਨਾਂ ਵਾਲੇ JWT ਨੂੰ plain text ਵਿੱਚ cache ਕਰ ਦਿੱਤਾ ਸੀ, ਇੱਕ ਹਕਰ ਨੇ ਇਸਨੂੰ ਕੱਢ ਲਿਆ ਅਤੇ ਕਿਸੇ ਦੂਜੇ ਦੇਸ਼ ਤੋਂ ਇਸਦੀ ਦੁਬਾਰਾ ਵਰਤੋਂ (replay) ਕੀਤੀ, ਅਤੇ ਇਸਦਾ ਇੱਕੋ ਇੱਕ ਹੱਲ signing key ਨੂੰ rotate ਕਰਨਾ ਸੀ—ਇੱਕ ਅਜਿਹਾ ਕੰਮ ਜਿਸ ਨੇ ਹਰ ਯੂਜ਼ਰ ਨੂੰ log out ਕਰ ਦਿੱਤਾ। ਇਸ ਘਟਨਾ ਨੇ ਕੰਪਨੀ ਦੀ token security ਨੂੰ ਨਵਾਂ ਰੂਪ ਦਿੱਤਾ ਅਤੇ ਹੁਣ ਇਹ video-streaming ਸੇਵਾ ਨੂੰ ਚਲਾ ਰਹੀ ਹੈ।

ਪੁਰਾਣਾ ਮਾਡਲ ਕਿਉਂ ਅਸਫਲ ਰਿਹਾ

JWTs (JSON Web Tokens) self-contained, signed blobs ਹੁੰਦੇ ਹਨ ਜੋ ਇੱਕ server ਨੂੰ database lookup ਤੋਂ ਬਿਨਾਂ request ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੇ ਹਨ। ਇਹ ਸਹੂਲਤ ਇੱਕ ਕੀਮਤ ਛੁਪਾਉਂਦੀ ਹੈ: ਜੇਕਰ ਇੱਕ token ਹਫ਼ਤਿਆਂ ਤੱਕ ਚੱਲਦਾ ਹੈ, ਤਾਂ ਇਸਨੂੰ ਚੋਰੀ ਕਰਨ ਨਾਲ ਹਕਰ ਨੂੰ ਹਫ਼ਤਿਆਂ ਤੱਕ access ਮਿਲ ਜਾਂਦਾ ਹੈ। ਇਸ breach ਵਿੱਚ, ਚੋਰੀ ਕੀਤਾ ਗਿਆ token ਆਪਣੇ 30-ਦਿਨਾਂ ਦੀ ਮਿਆਦ ਖਤਮ ਹੋਣ ਤੱਕ ਵੈਧ (valid) ਰਿਹਾ ਕਿਉਂਕਿ ਇਸਨੂੰ ਸਮੇਂ ਤੋਂ ਪਹਿਲਾਂ ਅਯੋਗ (invalidate) ਕਰਨ ਦਾ ਕੋਈ ਤਰੀਕਾ ਨਹੀਂ ਸੀ।

Signing key ਨੂੰ rotate ਕਰਨਾ ਸਾਰੇ tokens ਨੂੰ ਅਯੋਗ ਕਰਨ ਦਾ ਇੱਕੋ ਇੱਕ ਵਿਸ਼ਵਵਿਆਪੀ (global) ਤਰੀਕਾ ਹੈ, ਪਰ ਇਹ ਹਰ ਯੂਜ਼ਰ ਨੂੰ ਦੁਬਾਰਾ log in ਕਰਨ ਲਈ ਮਜਬੂਰ ਕਰਦਾ ਹੈ, ਜਿਸ ਨਾਲ ਸੇਵਾ ਵਿੱਚ ਵਿਘਨ ਪੈਂਦਾ ਹੈ ਅਤੇ ਭਰੋਸਾ ਘਟਦਾ ਹੈ। ਖਾਮੀ JWT ਵਿੱਚ ਨਹੀਂ ਸੀ, ਸਗੋਂ ਇੱਕ ਇਕੱਲੇ, ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲਣ ਵਾਲੇ credential 'ਤੇ ਨਿਰਭਰ ਰਹਿਣ ਵਿੱਚ ਸੀ।

ਨਵੇਂ ਡਿਜ਼ਾਈਨ ਦਾ ਸੰਖੇਪ ਵੇਰਵਾ

TrendVidStream ਹੁਣ ਦੋ ਕਿਸਮ ਦੇ tokens ਜਾਰੀ ਕਰਦਾ ਹੈ:

  • Access tokens – 15 ਮਿੰਟਾਂ ਲਈ ਵੈਧ; ਇਹ ਹਰੇਕ API call ਲਈ ਲੋੜੀਂਦੀਆਂ permissions ਰੱਖਦੇ ਹਨ।
  • Refresh tokens – ਇੱਕ ਵਾਰ ਵਰਤੋਂ ਵਾਲੇ tokens ਜੋ ਇੱਕ ਘੱਟ ਸਮੇਂ ਵਾਲੇ access token ਨੂੰ ਨਵੇਂ ਜੋੜੇ (pair) ਨਾਲ ਬਦਲ ਦਿੰਦੇ ਹਨ।

ਜਦੋਂ ਕੋਈ client refresh token ਪੇਸ਼ ਕਰਦਾ ਹੈ, ਤਾਂ server:

  1. Token ਦੇ signature ਅਤੇ claims ਦੀ ਪੁਸ਼ਟੀ ਕਰਦਾ ਹੈ।
  2. ਚੈੱਕ ਕਰਦਾ ਹੈ ਕਿ ਕੀ token ਦੀ ਪਹਿਲਾਂ ਹੀ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਚੁੱਕੀ ਹੈ।
  3. ਜੇਕਰ ਚੈੱਕ ਪਾਸ ਹੋ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਇੱਕ ਬਿਲਕੁਲ ਨਵਾਂ refresh token ਅਤੇ ਇੱਕ ਨਵਾਂ 15-ਮਿੰਟ ਦਾ access token ਜਾਰੀ ਕਰਦਾ ਹੈ।
  4. ਪੁਰਾਣੇ refresh token ਨੂੰ 'ਵਰਤਿਆ ਗਿਆ' (used) ਵਜੋਂ ਮਾਰਕ ਕਰਦਾ ਹੈ।

ਜੇਕਰ ਕਦਮ 2 ਅਸਫਲ ਰਹਿੰਦਾ ਹੈ—ਯਾਨੀ ਕਿ ਉਹੀ token ਦੂਜੀ ਵਾਰ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ—ਤਾਂ server ਇਸਨੂੰ ਚੋਰੀ ਦੇ ਸੰਕੇਤ ਵਜੋਂ ਲੈਂਦਾ ਹੈ ਅਤੇ ਉਸ login session ਨਾਲ ਜੁੜੇ tokens ਦੇ ਪੂਰੇ “family” ਨੂੰ ਰੱਦ (revoke) ਕਰ ਦਿੰਦਾ ਹੈ। ਪੀੜਤ ਅਤੇ ਹਕਰ ਦੋਵਾਂ ਨੂੰ ਦੁਬਾਰਾ log in ਕਰਨ ਲਈ ਮਜਬੂਰ ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਜਿਸ ਨਾਲ breach ਨੂੰ ਜਲਦੀ ਰੋਕ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ।

Token families ਦੀ ਟ੍ਰੈਕਿੰਗ

ਹਰੇਕ token ਨੂੰ ਇੱਕ ਵੱਖਰੇ ਰਿਕਾਰਡ ਵਜੋਂ ਮੰਨਣ ਦੀ ਬਜਾਏ, ਸਿਸਟਮ ਉਹਨਾਂ ਨੂੰ families ਵਿੱਚ ਗਰੁੱਪ ਕਰਦਾ ਹੈ ਜੋ ਯੂਜ਼ਰ ਦੇ log in ਕਰਨ ਵੇਲੇ ਸ਼ੁਰੂ ਹੁੰਦੀਆਂ ਹਨ। ਹਰ rotation ਉਸ family ਦਾ ਇੱਕ ਨਵਾਂ ਮੈਂਬਰ ਬਣਾਉਂਦਾ ਹੈ। Production ਵਿੱਚ ਵਰਤਿਆ ਜਾਣ ਵਾਲਾ SQLite schema ਇਹਨਾਂ ਨੂੰ ਸਟੋਰ ਕਰਦਾ ਹੈ:

  • family_id – ਪੂਰੇ session ਲਈ ਇੱਕ ਸਥਿਰ identifier।
  • token_id – ਹਰੇਕ refresh token ਲਈ ਇੱਕ ਵਿਲੱਖਣ (unique) identifier।
  • generation – debugging ਲਈ ਇੱਕ useful counter।
  • used_at – ਜਦੋਂ token ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਗਈ ਸੀ, ਉਸਦਾ timestamp।
  • revoked – ਇੱਕ flag ਜੋ, ਜਦੋਂ set ਕੀਤਾ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਪੂਰੀ family ਨੂੰ ਅਯੋਗ ਕਰ ਦਿੰਦਾ ਹੈ।

ਜਦੋਂ ਦੁਬਾਰਾ ਵਰਤੋਂ (reuse) ਦੀ ਘਟਨਾ ਦਾ ਪਤਾ ਲੱਗਦਾ ਹੈ, ਤਾਂ ਉਸ family_id ਲਈ revoked flag set ਕਰ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ, ਜਿਸ ਨਾਲ compromised session ਨਾਲ ਸਬੰਧਤ ਹਰ token ਤੁਰੰਤ ਅਯੋਗ ਹੋ ਜਾਂਦਾ ਹੈ। ਇਹ ਇੱਕ ਚੁੱਪਚਾਪ ਹੋਏ hijack ਨੂੰ ਇੱਕ high-signal alert ਵਿੱਚ ਬਦਲ ਦਿੰਦਾ ਹੈ ਜੋ logs ਵਿੱਚ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ।

ਤਿੰਨ ਲਾਗੂ ਕਰਨ ਦੇ ਨਿਯਮ ਜੋ ਸਿਸਟਮ ਨੂੰ ਭਰੋਸੇਯੋਗ ਰੱਖਦੇ ਹਨ

  1. ਪਹਿਲਾਂ signature ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ ਜੇਕਰ server signature ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ “used-before?” ਚੈੱਕ ਕਰਦਾ ਹੈ, ਤਾਂ ਇੱਕ ਹਕਰ token IDs ਦਾ ਅੰਦਾਜ਼ਾ ਲਗਾ ਸਕਦਾ ਹੈ ਅਤੇ ਵੱਡੇ ਪੱਧਰ 'ਤੇ revocations ਸ਼ੁਰੂ ਕਰ ਸਕਦਾ ਹੈ। ਪਹਿਲਾਂ ਪ੍ਰਮਾਣਿਕਤਾ (authenticity) ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਨਾਲ ਬੇਲੋੜੇ denial-of-service ਹਮਲਿਆਂ ਤੋਂ ਬਚਿਆ ਜਾ ਸਕਦਾ ਹੈ।

  2. Grace window ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ ਮੋਬਾਈਲ ਐਪਸ ਅਕਸਰ token ਦੀ ਮਿਆਦ ਖਤਮ ਹੋਣ 'ਤੇ ਲਗਾਤਾਰ ਦੋ refresh requests ਭੇਜਦੀਆਂ ਹਨ। ਜੇਕਰ server ਬਹੁਤ ਸਖ਼ਤ ਹੈ, ਤਾਂ ਦੂਜੀ request ਨੂੰ reuse ਵਜੋਂ ਫਲੈਗ ਕੀਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਇੱਕ ਜਾਇਜ਼ ਯੂਜ਼ਰ log out ਹੋ ਜਾਵੇਗਾ। ਕੁਝ ਸੈਕਿੰਡ ਦਾ buffer ਇੱਕ “ਵਰਤੇ ਹੋਏ” token ਨੂੰ ਵੀ ਨਵਾਂ ਜੋੜਾ ਵਾਪਸ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ, ਜਿਸ ਨਾਲ race conditions ਸੁਲਝ ਜਾਂਦੀਆਂ ਹਨ।

  3. ਪੂਰੇ flow ਨੂੰ row locking ਦੇ ਨਾਲ ਇੱਕ transaction ਵਿੱਚ ਰੱਖੋ Atomicity ਤੋਂ ਬਿਨਾਂ, ਦੋ ਇੱਕੋ ਸਮੇਂ ਆਉਣ ਵਾਲੀਆਂ (concurrent) requests ਦੋਵੇਂ ਇਹ ਸੋਚ ਸਕਦੀਆਂ ਹਨ ਕਿ ਉਹ token ਦੀ ਵਰਤੋਂ ਕਰਨ ਵਾਲੀਆਂ ਪਹਿਲੀਆਂ ਹਨ, ਜਿਸ ਨਾਲ ਦੁਬਾਰਾ refresh tokens ਜਾਰੀ ਹੋ ਸਕਦੇ ਹਨ ਅਤੇ single-use ਦੀ ਗਾਰੰਟੀ ਟੁੱਟ ਸਕਦੀ ਹੈ। ਇੱਕ database transaction ਜੋ token row ਨੂੰ lock ਕਰਦਾ ਹੈ, ਇਹ ਯਕੀਨੀ ਬਣਾਉਂਦਾ ਹੈ ਕਿ ਸਿਰਫ਼ ਇੱਕ ਹੀ request ਸਫਲ ਹੋਵੇ।

ਸਿੱਖਿਆ (Takeaway): refresh tokens ਨੂੰ single-use ਬਣਾ ਕੇ ਅਤੇ ਦੁਬਾਰਾ ਵਰਤੋਂ 'ਤੇ ਨਜ਼ਰ ਰੱਖ ਕੇ, ਇੱਕ ਸਿਸਟਮ ਹਰ ਚੋਰੀ ਕੀਤੇ ਗਏ credential ਨੂੰ ਇੱਕ ਅਲਾਰਮ ਵਿੱਚ ਬਦਲ ਸਕਦਾ ਹੈ, ਜੋ ਪਲੇਟਫਾਰਮ-ਵਿਆਪੀ logout ਕੀਤੇ ਬਿਨਾਂ ਯੂਜ਼ਰਾਂ ਦੀ ਰੱਖਿਆ ਕਰਦਾ ਹੈ।