system-design-bangla

ব্যাকএন্ড ইন্টারভিউ প্রশ্ন ও উত্তর

“Logout from All Devices” ফিচারটা কিভাবে Implement করা হয়?

সাধারণত User একাধিক Device (মোবাইল, ব্রাউজার, ল্যাপটপ) থেকে লগইন করে থাকে, প্রতিটা Login এর জন্য আলাদা Token ইস্যু হয়। “Logout from all devices” মানে হচ্ছে একসাথে সবগুলো Device এর সব Token কে একবারে Invalidate করে দেয়া।

এটা Implement করার কয়েকটা common approach আছে,

ধরুন কেউ JWT এর Payload decode করে role: user পরিবর্তন করে role: admin করে দিল। তাহলে কি সে Admin Access পেয়ে যাবে, নাকি Server সেটা ধরে ফেলবে?

না, শুধুমাত্র Payload পরিবর্তন করলেই কেউ Admin হয়ে যেতে পারবে না।

Server যখন কোনো JWT পায়, তখন Header এবং Payload নিয়ে আবার নিজের Secret/Public Key দিয়ে একটা নতুন Signature বানায়, এবং সেটা token এর সাথে আসা Signature এর সাথে মিলিয়ে দেখে। দুটো মিললেই Server নিশ্চিত হয় token টা valid এবং কেউ Tamper করেনি।

কেউ যদি Payload এর ভিতরের ডাটা (যেমন role: user কে role: admin বানিয়ে) পরিবর্তন করে, তাহলে Signature আর মিলবে না (কারণ Signature টা আগের Payload দিয়ে বানানো হয়েছিল), Server সাথে সাথে সেই Token কে Invalid/Unauthorized ধরে reject করে দিবে।

Password কেন Hash করা হয়, Encrypt করা হয় না কেন?

Encryption একটা Two-way প্রসেস, মানে Encrypt করা ডাটাকে সঠিক Key দিয়ে আবার Decrypt করে আসল ডাটায় ফেরত আনা যায়। অন্যদিকে, Hashing একটা One-way প্রসেস, মানে Hash থেকে আসল ডাটা (Plain Text) ফেরত পাওয়ার কোনো সরাসরি উপায় নেই।

Password-এর ক্ষেত্রে আমাদের আসল Password পরে পড়ার বা ফেরত পাওয়ার প্রয়োজন হয় না; শুধু Login-এর সময় ব্যবহারকারীর দেওয়া Password সঠিক কিনা সেটি যাচাই করাই যথেষ্ট। তাই Password Database-এ সংরক্ষণের জন্য Encryption-এর পরিবর্তে Hashing ব্যবহার করা হয়।

যদি Password Encryption ব্যবহার করে সংরক্ষণ করা হতো, তাহলে Server-কে Decryption Key সংরক্ষণ করতে হতো। সেই Key কোনোভাবে ফাঁস হয়ে গেলে বা চুরি হয়ে গেলে, Database-এর সব Password সহজেই উদ্ধার করা সম্ভব হতো।

কিন্তু Hashing ব্যবহার করলে Database Leak হলেও Attackers সরাসরি User-এর আসল Password জানতে পারে না। Login-এর সময় User যে Password দেয় সেটিকে আবার Hash করে Database-এ সংরক্ষিত Hash-এর সাথে মিলিয়ে দেখা হয়। দুইটি Hash মিলে গেলে User-কে Authenticate করা হয়।

JWT ব্যবহারের সাথে জড়িত Security Risk গুলো কি কি?

JWT Stateless Authentication-এর জন্য খুবই জনপ্রিয়, কিন্তু ভুলভাবে ব্যবহার করলে এটি বড় ধরনের Security Risk তৈরি করতে পারে।

আপনার কাছে JWT access token আছে যার মেয়াদ ১৫ মিনিট, এবং refresh token আছে যার মেয়াদ ৩০ দিন। একজন user-এর refresh token চুরি হয়ে যায়। আপনি কীভাবে এটি শনাক্ত করবেন এবং বাতিল করবেন?

আমি Refresh Token Rotation + Server-side Tracking ব্যবহার করব।

Access token-কে আমি stateless JWT রাখব এবং এর expiry 15 মিনিট রাখব। কিন্তু refresh token-এর জন্য database-এ jti বা token-এর hash, সাথে userId, familyId, expiresAt, revokedAt ইত্যাদি রাখব।

প্রতিবার refresh token ব্যবহার হলে পুরোনো refresh token-টি revoke করে নতুন refresh token issue করব।

যেমন:

RT1 → RT2 → RT3

ধরুন, attacker RT2 চুরি করেছে। কিন্তু legitimate user ইতিমধ্যে RT2 ব্যবহার করে RT3 পেয়ে গেছে। তাই database-এ RT2 এখন revoked থাকবে।

পরে attacker যদি আবার RT2 দিয়ে refresh করার চেষ্টা করে, আমি বুঝতে পারব যে একটি revoked refresh token আবার ব্যবহার করা হচ্ছে। এটাকে আমি refresh token reuse detection হিসেবে ধরব।

তখন আমি পুরো token family revoke করব:

RT1 ❌ → RT2 ❌ → RT3 ❌

এরপর 401 Unauthorized return করব এবং user-কে আবার login করতে বলব।

আর যদি legitimate user এখনো RT2 ব্যবহার না করে থাকে, তাহলে শুধুমাত্র JWT দেখে আমি বুঝতে পারব না যে RT2 চুরি হয়েছে। কারণ attacker-এর কাছে থাকা RT2 এবং legitimate user’s RT2 একই valid token।

এখানে সবচেয়ে গুরুত্বপূর্ণ বিষয় হলো, HttpOnly cookie JavaScript দিয়ে read করা বন্ধ করে, কিন্তু browser-কে cookie automatically send করা থেকে বন্ধ করে না।

backend developer হিসেবে কী করব আমি যা করব,

Cookie-তে SameSite সেট করব

Set-Cookie: session=abc123;
HttpOnly;
Secure;
SameSite=Strict

তাহলে অন্য malicious website থেকে:

POST https://bank.com/api/transfer

request গেলেও browser সাধারণত bank.com-এর session cookie cross-site context-এ পাঠাবে না।

এখানে CORS-এর কি কোনো ভূমিকা আছে?

না। CORS আর CSRF দুইটা আলাদা security problem solve করে।

CORS-এর কাজ মূলত হলো:

evil.com কি bank.com থেকে response পড়তে পারবে?

আপনি যদি বলেন:

Access-Control-Allow-Origin: https://bank.com

তাহলে evil.com response পড়তে পারবে না।

CSRF attack-এর জন্য attacker-এর সবসময় response পড়া দরকার হয় না।

ধরুন attacker শুধু এই request পাঠাতে পারল:

POST /api/transfer
Cookie: session=abc123

{
    "to": "attacker",
    "amount": 50000
}

যদি server request process করে ফেলে:

$50,000 transfer
       ↓
attacker account

তাহলে attack সফল। Attacker response পেল কি পেল না—এটা এখানে মূল সমস্যা না।

PKCE authorization code interception ঠেকায়, আর state parameter CSRF/response injection ঠেকায় — দুটোর attack vector ঠিক কোথায় আলাদা, ব্যাখ্যা করুন। যদি আপনার flow-তে শুধু state verification থাকে কিন্তু PKCE না থাকে, তাহলে কোন attack তখনও সম্ভব থেকে যায়? উল্টোটা হলে (PKCE আছে, state নেই) কী ঝুঁকি থেকে যায়? দুটো mechanism একসাথে থাকলে overall security guarantee-টা কী দাঁড়ায়?

PKCE (Proof Key for Code Exchange)

PKCE মূলত authorization code interception attack থেকে protection দেয়। OAuth flow শুরু করার সময় client একটি random code_verifier তৈরি করে এবং তার থেকে code_challenge তৈরি করে। পরে authorization code দিয়ে token নিতে গেলে original code_verifier দিতে হয়।

তাই কোনো attacker authorization code পেয়ে গেলেও code_verifier ছাড়া সেটি দিয়ে token নিতে পারবে না।

সংক্ষেপে:

PKCE ব্যবহার করলে authorization code চুরি হলেও attacker সেটি ব্যবহার করে access/refresh token নিতে পারে না।

State Verification

state parameter মূলত CSRF এবং OAuth response injection attack প্রতিরোধ করে। OAuth শুরু করার সময় application একটি cryptographically random state তৈরি করে এবং সেটি initiating browser/session-এর সাথে bind করে রাখে। OAuth callback আসার পর returned state এবং expected state match করতে হবে।

Match না করলে request reject করতে হবে—এবং ideally authorization code exchange বা কোনো data persist করার আগেই validation করতে হবে।

সংক্ষেপে:

State verification নিশ্চিত করে যে OAuth callback-টি সত্যিই যে browser/user OAuth flow শুরু করেছিল, সেখান থেকেই এসেছে।