CSRF দুর্বলতার একটি বাস্তব উদাহরণ
CSRF দুর্বলতার একটি বাস্তব উদাহরণ
গল্পের শুরু
ধরি, সেলিনা একজন অনলাইন ব্যাঙ্কের ব্যবহারকারী। তিনি নিয়মিতভাবে তার ব্যাংক অ্যাকাউন্টে লগ ইন করেন এবং অনলাইনে লেনদেন করেন। একদিন, সেলিনা একটি ফেসবুক পোস্টে একটি লিঙ্ক দেখতে পান, যা তাকে বলে, “দারুণ একটি ফ্রি গিফট পেতে ক্লিক করুন!” লিঙ্কটি ছিল একটি ম্যালিসিয়াস ওয়েবসাইটের (যাকে আমরা বলব evil.com)।
হ্যাকার ওয়েবসাইট
<!-- Evil.com - Attacker's site -->
<html>
<head>
<title>Claim Your Free Gift!</title>
</head>
<body>
<h1>Claim Your Free Gift!</h1>
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="amount" value="1000">
<button type="submit">Click Here to Get It!</button> <!-- Deceptive button text -->
</form>
</body>
</html>
ঘটনার বিবরণ
- সেলিনা ক্লিক করে: সেলিনা লিঙ্কটিতে ক্লিক করে এবং ম্যালিসিয়াস সাইটে পৌঁছে। এখানে একটি ফর্ম রয়েছে যা একটি ব্যাংক ট্রান্সফার করবে।
- ফর্মটি সম্পন্ন হয়: যখন সে “Click Here to Get It!” বোতামে ক্লিক করে, এটি একটি POST অনুরোধ তৈরি করে, যা ব্যাংকের সার্ভারে পাঠানো হয়, যেখানে 1000 টাকা ট্রান্সফার করার জন্য একটি হিডেন ইনপুট ফিল্ড রয়েছে।
- ব্যাংক সার্ভার প্রক্রিয়া করে: ব্যাংকের সার্ভার সেলিনার জন্য সক্রিয় সেশন কুকি দেখে এবং অনুরোধটি বৈধ মনে করে। ফলে ট্রান্সফারটি সম্পন্ন হয়, কিন্তু সেলিনা জানেও না যে তার টাকা চলে যাচ্ছে।
বাস্তব উদাহরণ
ধরা যাক, আমরা একটি ব্যাঙ্কের ওয়েবসাইট (bank.com) এবং একটি হ্যাকার সাইট (evil.com) নিয়ে কথা বলছি।
১. Strict SameSite
ব্যাঙ্কের সাইটের কুকি সেট করা হয়েছে:
Set-Cookie: sessionid=abc123; SameSite=Strict
এখন, যদি একটি ব্যবহারকারী হ্যাকার সাইটে (evil.com) একটি ফর্ম জমা দেয় যা ব্যাঙ্কের ট্রান্সফার API এ রিকোয়েস্ট পাঠাচ্ছে:
<!-- Evil.com - Attacker's site -->
<form action="https://bank.com/transfer" method="POST">
<label for="amount">Transfer Amount:</label>
<input type="text" id="amount" name="amount" value="1000" readonly>
<button type="submit">Click me to transfer 1000</button>
</form>
ব্যবহারকারী যদি এই ফর্মটি জমা দেয়, তবে কুকিটি (sessionid) ব্যাংক সাইটে পাঠানো হবে না কারণ কুকিটি SameSite=Strict সেট করা হয়েছে। ফলে, ব্যাংক সাইটে এ রিকোয়েস্ট প্রত্যাখ্যাত হবে এবং নিরাপত্তা বজায় থাকবে।
২. Lax SameSite
যদি ব্যাংক সাইটের কুকি সেট করা হয়:
Set-Cookie: sessionid=abc123; SameSite=Lax
এই ক্ষেত্রে, ব্যবহারকারী যদি ফর্মটি জমা দেয়, তখন GET রিকোয়েস্টের ক্ষেত্রে কুকিটি ব্যাংক সাইটে পাঠানো হবে, কিন্তু POST রিকোয়েস্টে পাঠানো হবে না।
৩. None SameSite
যদি ব্যাংক সাইটের কুকি সেট করা হয়:
Set-Cookie: sessionid=abc123; SameSite=None; Secure
এই অবস্থায়, সব ধরনের অনুরোধের জন্য কুকিটি পাঠানো হবে। যদি একজন হ্যাকার সফলভাবে রিকোয়েস্ট পাঠায়, তবে ব্যাঙ্ক সাইটটি সেই অনুরোধ গ্রহণ করবে, যা CSRF আক্রমণের সম্ভাবনা বাড়ায়। এজন্য এটি HTTPS সংযোগে হতে হবে।
সারসংক্ষেপ
SameSite অ্যাট্রিবিউট কুকির নিরাপত্তা বাড়ানোর জন্য একটি কার্যকরী পদ্ধতি। এটি নিশ্চিত করে যে কুকি শুধুমাত্র নির্দিষ্ট সাইটের জন্য উপলব্ধ, ফলে CSRF আক্রমণ থেকে রক্ষা পাওয়া যায়।
CSRF টোকেনের কাজ
CSRF টোকেন হল একটি নিরাপত্তা ব্যবস্থা যা নিশ্চিত করে যে একজন ব্যবহারকারী শুধুমাত্র বৈধভাবে উত্সিত অনুরোধগুলি করে।
- টোকেন উৎপাদন: যখন ব্যবহারকারী ব্যাঙ্ক সাইটে লগ ইন করে, তখন সার্ভার একটি ইউনিক CSRF টোকেন তৈরি করে এবং এটি ব্যবহারকারীর কুকিতে সেভ করে।
- অনুরোধ পাঠানো: ব্যবহারকারী যখন লেনদেন করতে চান, তখন সেই CSRF টোকেনটি ফর্মের সাথে পাঠানো হয়।
- সার্ভার যাচাই করে: সার্ভার এই টোকেনটি যাচাই করে এবং নিশ্চিত হয় যে এটি বৈধ। যদি টোকেনটি সঠিক হয়, তখন অনুরোধটি প্রক্রিয়া করা হয়।
SameSite Cookie Attribute
SameSite Cookie Attribute একটি নিরাপত্তা বৈশিষ্ট্য যা কুকিকে সীমাবদ্ধ করে। এটি কুকিকে ব্যবহার করার সময় তা শুধুমাত্র নির্দিষ্ট সাইটের জন্য উপলব্ধ করে। এটি Cross-Site Request Forgery (CSRF) আক্রমণ প্রতিরোধে সাহায্য করে।
কাজের প্রক্রিয়া
SameSite অ্যাট্রিবিউটের তিনটি ভ্যালু রয়েছে:
- Strict: কুকি শুধুমাত্র সেই সাইটের জন্য পাঠানো হয়, যেখানে এটি সেট করা হয়েছে। অন্য সাইট থেকে কোন অনুরোধ এলে কুকি পাঠানো হয় না।
- Lax: কুকি সাধারণত প্রথম পক্ষের সাইটে পাঠানো হয়, তবে সীমিত কিছু ক্রিয়াকলাপ (যেমন GET লিঙ্ক ক্লিক করা) Cross-Site রিকোয়েস্টে কুকি পাঠানো হতে পারে।
- None: কুকি সব ক্ষেত্রে পাঠানো হবে। তবে এটি HTTPS সংযোগে থাকতে হবে।
Django তে CSRF টোকেন জেনারেট করা
Django-তে CSRF টোকেন ব্যবহার করা সহজ। সাধারণত, Django csrf_token টেমপ্লেট ট্যাগ ব্যবহার করে একটি CSRF টোকেন জেনারেট করে।
Django কোড উদাহরণ
- settings.py এ CSRF সুরক্ষা সক্ষম করুন (ডিফল্টভাবে এটি সক্ষম থাকে):
MIDDLEWARE = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
]
- টেমপ্লেট ফাইলে CSRF টোকেন যুক্ত করুন:
<form method="POST">
{% csrf_token %}
<input type="text" name="amount" placeholder="Enter amount">
<button type="submit">Transfer</button>
</form>
- API ViewSet এ
dispatchমেথড ব্যবহার করুন:
from rest_framework import viewsets
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from rest_framework.response import Response
@method_decorator(csrf_protect, name='dispatch')
class TransferViewSet(viewsets.ViewSet):
def create(self, request):
amount = request.data.get('amount')
# এখানে লজিক যুক্ত করুন
return Response({'message': 'Transfer successful'})
ReactJS ক্লায়েন্ট সাইডে CSRF টোকেন পাঠানো
CSRF টোকেন নেওয়া
প্রথমে, Django থেকে CSRF টোকেন নেওয়ার জন্য getCookie ফাংশনটি ব্যবহার করা হবে:
// CSRF টোকেন পাওয়ার জন্য একটি ফাংশন
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// যদি টোকেনের নাম পাওয়া যায়
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
React কম্পোনেন্ট তৈরি করা
এখন আমরা একটি React কম্পোনেন্ট তৈরি করব যেখানে আমরা একটি নতুন ট্রান্সফার তৈরি করব। CSRF টোকেনটি ফর্ম সাবমিশনের সময় পাঠানো হবে।
import React, { useState } from 'react';
import axios from 'axios';
const TransferForm = () => {
const [amount, setAmount] = useState('');
const handleSubmit = async (event) => {
event.preventDefault();
// CSRF টোকেন পাওয়া
const csrftoken = getCookie('csrftoken');
try {
const response = await axios.post('https://pahona.org/api/wp-json/custom/v1/transfer/', {
amount: amount
}, {
headers: {
'X-CSRFToken': csrftoken // CSRF টোকেন পাঠানো
}
});
console.log('Transfer Created:', response.data);
// ফর্ম ক্লিয়ার করা
setAmount('');
} catch (error) {
console.error('Error creating Transfer:', error);
}
};
return (
<form onSubmit={handleSubmit}>
<label>
Transfer Amount:
<input
type="number"
value={amount}
onChange={(e) => setAmount(e.target.value)}
required
/>
</label>
<button type="submit">Submit</button>
</form>
);
};
export default TransferForm;
ব্যাখ্যা:
- getCookie ফাংশন: এই ফাংশনটি ব্রাউজারের কুকি থেকে CSRF টোকেন পেতে সাহায্য করে।
- handleSubmit ফাংশন: ফর্মটি সাবমিট করার সময় এই ফাংশনটি কল হয়। এটি CSRF টোকেন সহ POST অনুরোধ পাঠায়।
- axios POST অনুরোধ:
axios.postব্যবহার করে আমরা আমাদের API এ অনুরোধ পাঠাচ্ছি, যেখানে CSRF টোকেনটি হেডারে অন্তর্ভুক্ত করা হয়েছে।
Conclusion
CSRF আক্রমণগুলি একটি সাধারণ কিন্তু মারাত্মক নিরাপত্তা সমস্যা। CSRF টোকেন এবং SameSite কুকি অ্যাট্রিবিউট ব্যবহার করে, আপনি আপনার অ্যাপ্লিকেশনকে এই ধরনের আক্রমণের বিরুদ্ধে সুরক্ষিত রাখতে পারেন। সচেতনতা এবং সঠিক কোডিং প্রাকটিসগুলি অপরিহার্য।