PHP প্রসেসিং ফর্ম (Processing Forms) PHP ক্রস-সাইট রিকোয়েস্ট ফ্রগেরই (CSRF) Estimated reading: 4 minutes 11 views Contributors সারাংশ: এই টিউটোরিয়ালে, আপনি ক্রস-সাইট রিকোয়েস্ট ফোরজি (CSRF) আক্রমণ এবং পিএইচপি-তে কীভাবে তাদের প্রতিরোধ করবেন সে সম্পর্কে শিখবেন। CSRF কিCSRF মানে ক্রস-সাইট অনুরোধ জালিয়াতি। এটি এমন এক ধরণের আক্রমণ যেখানে একজন হ্যাকার আপনাকে এমন একটি ওয়েবসাইটের বিরুদ্ধে একটি পদক্ষেপ করতে বাধ্য করে যেখানে আপনি বর্তমানে লগ ইন করেছেন।উদাহরণস্বরূপ, আপনি malicious-site.com-এ যান যার একটি লুকানো ফর্ম রয়েছে৷ এবং সেই ফর্মটি yourbank.com/transfer-fund ফর্মে পৃষ্ঠা লোডের পরে জমা দেয়।যেহেতু আপনি বর্তমানে yourbank.com-এ লগ ইন করেছেন, তাই অনুরোধটি নীরবে আপনার ব্যাঙ্ক অ্যাকাউন্ট থেকে একটি তহবিল স্থানান্তর করে।yourbank.com/transfer-fund সঠিকভাবে CSRF প্রয়োগ করলে, এটি একটি এককালীন টোকেন তৈরি করে এবং তহবিল স্থানান্তর ফর্মে এইভাবে টোকেন সন্নিবেশ করায়:<input type="hidden" name="token" value="b3f44c1eb885409c222fdb78c125f5e7050ce4f3d15e8b15ffe51678dd3a33d3a18dd3">malicious-site.com ফর্মটি জমা দিলে, yourbank.com/transfer-fund ফর্মটি yourbank.com-এর সার্ভারে থাকা টোকেনের সাথে তুলনা করে।যদি জমা দেওয়া ডেটাতে টোকেনটি না থাকে বা এটি সার্ভারে থাকা টোকেনের সাথে না মেলে, তবে ফান্ড ট্রান্সফার ফর্ম জমাটি প্রত্যাখ্যান করবে এবং একটি ত্রুটি ফেরত দেবে।যখন malicious-site.com ফর্মটি জমা দেওয়ার চেষ্টা করে, তখন টোকেনটি পাওয়া যাবে না বা মিলবে না।PHP তে CSRF টোকেন কীভাবে প্রয়োগ করবেনপ্রথমে, একটি এককালীন টোকেন তৈরি করুন এবং এটিকে $_SESSION ভেরিয়েবলে যোগ করুন:$_SESSION['token'] = md5(uniqid(mt_rand(), true));দ্বিতীয়ত, একটি লুকানো ক্ষেত্র যোগ করুন যার মান হল টোকেন এবং ফর্মটিতে এটি সন্নিবেশ করান:<input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?? '' ?>">তৃতীয়ত, ফর্মটি জমা দেওয়ার সময়, INPUT_POST-এ টোকেনটি বিদ্যমান আছে কিনা তা পরীক্ষা করুন এবং এটিকে $_SESSION[‘token’]-এর সাথে তুলনা করুন:<?php $token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING); if (!$token || $token !== $_SESSION['token']) { // return 405 http status code header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed'); exit; } else { // process the form }যদি টোকেনটি বিদ্যমান না থাকে বা মেলে না, তাহলে 405 HTTP স্ট্যাটাস কোড ফেরত দিন এবং প্রস্থান করুন।PHP CSRF উদাহরণকিভাবে একটি CSRF আক্রমণ প্রতিরোধ করা যায় তা প্রদর্শন করার জন্য আমরা একটি সাধারণ তহবিল স্থানান্তর ফর্ম তৈরি করব:প্রথমে, নিম্নলিখিত ফাইল এবং ডিরেক্টরি তৈরি করুন:. ├── css │ └── style.css ├── inc │ ├── footer.php │ ├── get.php │ ├── header.php │ └── post.php └── index.phpheader.php header.php ফাইলটিতে এমন কোড রয়েছে যা পৃষ্ঠার প্রথম বিভাগটি দেখায়:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/style.css"> <title>PHP CSRF - Fund Transfer Demo</title> </head> <body> <main>footer.php footer.php ফাইলটিতে header.php ফাইলের খোলার ট্যাগের সাথে সম্পর্কিত ক্লোজিং ট্যাগ রয়েছে: </main> </body> </html>index.php ফাইল নিম্নলিখিত কোডটি index.php ফাইলে রাখুন:<?php session_start(); require __DIR__ . '/inc/header.php'; $errors = []; // for storing the error messages $inputs = []; // for storing sanitized input values $request_method = strtoupper($_SERVER['REQUEST_METHOD']); if ($request_method === 'GET') { // generate a token $_SESSION['token'] = bin2hex(random_bytes(35)); // show the form require __DIR__ . '/inc/get.php'; } elseif ($request_method === 'POST') { // handle the form submission require __DIR__ . '/inc/post.php'; // re-display the form if the form contains errors if ($errors) { require __DIR__ . '/inc/get.php'; } } require __DIR__ . '/inc/footer.php'; কিভাবে index.php কাজ করে। প্রথমে, session_start() ফাংশন কল করে একটি নতুন সেশন শুরু করুন; ত্রুটি বার্তা সংরক্ষণ করতে $errors অ্যারে ব্যবহার করুন এবং $inputs অ্যারে স্যানিটাইজড ইনপুট মান সংরক্ষণ করতে হয়।এরপর, যদি HTTP অনুরোধ GET হয় তাহলে get.php ফাইলে ফর্মটি দেখান। নিম্নলিখিত এক-কালীন টোকেন তৈরি করে:$_SESSION['token'] = bin2hex(random_bytes(35));random_bytes(35) 35টি অক্ষর সহ একটি এলোমেলো স্ট্রিং তৈরি করে। এবং bin2hex() ফাংশন র্যান্ডম স্ট্রিং এর হেক্সাডেসিমেল উপস্থাপনা প্রদান করে। টোকেন এই মত দেখাবে:c4724e490407a1770efcc4ea19776c06e0bd4614a9dd37900f5eb001581dffee9b377aতারপর, যদি HTTP অনুরোধটি POST হয় তবে ফর্ম জমা দেওয়ার জন্য post.php ফাইল থেকে কোডটি লোড করুন।এর পরে, ফর্ম ডেটা ভুল হলে ত্রুটি বার্তা সহ ফর্মটি আবার দেখান৷ মনে রাখবেন যে ফর্মটিতে ত্রুটি থাকলে, $errors-এ ত্রুটির বার্তা থাকবে।অবশেষে, তহবিল সফলভাবে স্থানান্তর করা হয়েছে তা জানানোর জন্য message.php ফাইল থেকে একটি বার্তা প্রদর্শন করুন। get.php নিম্নলিখিত দুটি ইনপুট ক্ষেত্র স্থানান্তর পরিমাণ এবং প্রাপকের অ্যাকাউন্ট সহ তহবিল স্থানান্তর ফর্ম তৈরি করে:<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post"> <header> <h1>Fund Transfer</h1> </header> <div> <label for="amount">Amount (between $1-$5000):</label> <input type="number" name="amount" value="<?= $inputs['amount'] ?? '' ?>" id="amount" placeholder="Enter the transfered amount"> <small><?= $errors['amount'] ?? '' ?></small> </div> <div> <label for="recipient_account">Recipient Account:</label> <input type="number" name="recipient_account" value="<?= $inputs['recipient_account'] ?? '' ?>" id="recipient_account" placeholder="Enter the recipient account"> <small><?= $errors['recipient_account'] ?? '' ?></small> </div> <input type="hidden" name="token" value="<?= $_SESSION['token'] ?? '' ?>"> <button type="submit">Transfer Now</button> </form>post.php নিম্নলিখিত কোড টোকেন এবং ফর্ম ডেটা যাচাই করে:<?php $token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING); if (!$token || $token !== $_SESSION['token']) { // show an error message echo '<p class="error">Error: invalid form submission</p>'; // return 405 http status code header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed'); exit; } // Validate amount $amount = filter_input(INPUT_POST, 'amount', FILTER_SANITIZE_NUMBER_INT); $inputs['amount'] = $amount; if ($amount) { $amount = filter_var( $amount, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1, 'max_range' => 5000]] ); if (!$amount) { $errors['amount'] = 'Please enter a valid amount (from $1 to $5000)'; } } else { $errors['amount'] = 'Please enter the transfered amount.'; } // validate account (simple) $recipient_account = filter_input(INPUT_POST, 'recipient_account', FILTER_SANITIZE_NUMBER_INT); $inputs['recipient_account'] = $recipient_account; if ($recipient_account) { $recipient_account = filter_var($recipient_account, FILTER_VALIDATE_INT); if (!$recipient_account) { $errors['recipient_account'] = 'Please enter a valid recipient account'; } // validate the recipient account against the database // ... } else { $errors['recipient_account'] = 'Please enter the recipient account.'; }কিভাবে post.php কাজ করে। প্রথমে, INPUT_POST থেকে টোকেনটি স্যানিটাইজ করুন:$token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING);filter_input() ফাংশনটি শূন্য প্রদান করে যদি টোকেন জমা দেওয়া ডেটাতে অন্তর্ভুক্ত করা হয়। FILTER_SANITIZE_STRING ফিল্টারটি টোকেন ফিল্টার করতে ব্যর্থ হলে এটি মিথ্যা ফেরত দেয়।দ্বিতীয়ত, $_SESSION ভেরিয়েবলে সংরক্ষিত একটি স্যানিটাইজড টোকেনের সাথে তুলনা করুন:if (!$token || $token !== $_SESSION['token']) { // process error }যদি সেগুলি মেলে না, আমরা হেডার() ফাংশন ব্যবহার করে ক্লায়েন্টকে HTTP স্ট্যাটাস কোড 405 (পদ্ধতি অনুমোদিত নয়) ফেরত দিই এবং সঙ্গে সঙ্গে স্ক্রিপ্ট বন্ধ করে দিই।header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed');অবশিষ্ট কোড স্যানিটাইজ করে এবং পরিমাণ এবং প্রাপকের অ্যাকাউন্ট যাচাই করে। যদি কোন ত্রুটি না থাকে, আমরা একটি নিশ্চিতকরণ বার্তা দেখাই:<?php if (!$errors) : ?> <section> <div class="circle"> <div class="check"></div> </div> <h1 class="message">You've transfered</h1> <h2 class="amount">$<?= $amount ?></h2> <a href="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" rel="prev">Done</a> </section> <?php endif ?>সারসংক্ষেপCSRF আক্রমণগুলি ব্যবহারকারীদের সেই সাইটের বিরুদ্ধে একটি পদক্ষেপ চালাতে বাধ্য করে যেখানে তারা বর্তমানে লগ ইন করেছে৷ এককালীন টোকেন তৈরি করতে bin2hex(random_bytes(35)) ব্যবহার করুন।CSRF আক্রমণ প্রতিরোধ করতে $_SESSION-এ সংরক্ষিত একটি দিয়ে জমা দেওয়া টোকেনটি পরীক্ষা করুন। PHP প্রসেসিং ফর্ম (Processing Forms) - Previous PHP সিলেক্ট অপশন (Select) Next - PHP প্রসেসিং ফর্ম (Processing Forms) PHP ফ্ল্যাশ বার্তা (Flash messages)