← Back to PHP Course | Chapter 10: Forms & Validation | Lesson 5 of 8

PHP CSRF Protection

CSRF एक trick है जहाँ एक bad site आपके browser से secretly एक request भेजवाता है जबकि आप कहीं और logged in हैं। एक protection token real forms पर एक secret stamp जैसा है ताकि site fakes पकड़ सके।
Syntax
php
session_start();
$_SESSION["csrf_token"] = bin2hex(random_bytes(32));

// in the form:
// <input type="hidden" name="csrf_token" value="<?= $_SESSION["csrf_token"] ?>">

if (hash_equals($_SESSION["csrf_token"], $_POST["csrf_token"])) {
    // request is genuine
}

CSRF क्या है?

Cross-Site Request Forgery किसी logged-in user के browser को उनकी जानकारी के बिना आपकी site पर एक request submit करने के लिए trick करता है, किसी दूसरे page पर एक malicious form या link embed करके जिसे वे visit कर लेते हैं।

उदाहरण: What is CSRF?

php
<?php
// A malicious page could auto-submit this hidden form using the victim's session
echo '<form action="https://bank.example.com/transfer" method="POST">
  <input type="hidden" name="amount" value="1000">
</form>';
?>

एक CSRF Token Generate करना

एक CSRF token प्रति session (या प्रति form) generate की गई एक random, unpredictable value है और एक hidden form field की तरह embedded है, जिसे आपका server फिर submission पर match करने के लिए verify करता है — एक attacker की forged request को यह value जानने का कोई तरीका नहीं है।

उदाहरण: Generating a CSRF Token

php
<?php
// Call `session_start()`
session_start();
// Set `$_SESSION['csrf_token']` to `bin2hex(random_bytes(16))`
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
// Print `$_SESSION['csrf_token']` to the output
echo $_SESSION['csrf_token'];
?>

Forms में Tokens Add करना

random_bytes() जैसे एक cryptographically secure function से token generate करें, इसे $_SESSION में store करें, और comparison में timing-attack vulnerabilities से बचने के लिए submission पर hash_equals() से इसे compare करें।

उदाहरण: Adding Tokens to Forms

php
<?php
// Call `session_start()`
session_start();
// Set `$_SESSION['csrf_token']` to `bin2hex(random_bytes(16))`
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
// Print '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">' to the output
echo '<input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">';
?>

CSRF Token Verify करना

CSRF protection specifically state-changing requests (कोई भी चीज़ जो data modify करती है, जैसे password change या purchase) के लिए मायने रखती है — read-only GET requests आमतौर पर इस defense का concern नहीं होतीं।

उदाहरण: Verifying the CSRF Token

php
<?php
// Call `session_start()`
session_start();
// Set `$_SESSION['csrf_token']` to "abc123"
$_SESSION['csrf_token'] = "abc123";
// Set `$_POST['csrf_token']` to "abc123"
$_POST['csrf_token'] = "abc123";
// Check whether `hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])`
if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    // Print "Token valid -- proceed with the state-changing action" to the output
    echo "Token valid -- proceed with the state-changing action";
// Otherwise, run this branch
} else {
    // Print "Token mismatch -- reject request" to the output
    echo "Token mismatch -- reject request";
}
?>

Used Tokens Clear करना

Laravel और Symfony जैसे ज़्यादातर PHP frameworks आपके लिए automatically CSRF tokens generate और verify करते हैं, जो data बदलने वाली किसी भी चीज़ के लिए raw HTML forms हाथ से बनाने के बजाय framework के form helpers को prefer करने की एक strong वजह है।

उदाहरण: Clearing Used Tokens

php
<?php
// Call `session_start()`
session_start();
// Set `$_SESSION['csrf_token']` to "abc123"
$_SESSION['csrf_token'] = "abc123";
// Remove `$_SESSION['csrf_token']`
unset($_SESSION['csrf_token']);
// Print `isset($_SESSION['csrf_token']) ? "Still set" : "Token cleared after use"` to the output
echo isset($_SESSION['csrf_token']) ? "Still set" : "Token cleared after use";
?>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. random_bytes या bin2hex(random_bytes(32)) के बजाय एक predictable token इस्तेमाल करना।
  2. tokens को == से compare करना, जबकि hash_equals timing attacks से बचाता है।
  3. POST requests के लिए server पर token check करना भूल जाना।
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.