Rumah > pembangunan bahagian belakang > tutorial php > Perlindungan CSRF dalam PHP

Perlindungan CSRF dalam PHP

Patricia Arquette
Lepaskan: 2024-12-09 04:41:11
asal
343 orang telah melayarinya

CSRF Protection in PHP

Apakah CSRF?

Pemalsuan Permintaan Silang Tapak (CSRF) ialah kerentanan keselamatan web yang membenarkan penyerang memperdaya pengguna yang disahkan supaya melaksanakan tindakan yang tidak diingini pada tapak web yang mereka log masuk pada masa ini. Serangan itu berfungsi dengan mengeksploitasi kepercayaan yang dimiliki tapak web dalam penyemak imbas pengguna.

Cara Serangan CSRF Berfungsi

  1. Pengguna log masuk ke tapak web A yang sah dan menerima kuki sesi
  2. Pengguna melawat tapak web berniat jahat B semasa masih log masuk ke A
  3. Tapak web B mengandungi kod yang membuat permintaan ke tapak web A
  4. Pelayar menyertakan kuki sesi secara automatik
  5. Tapak Web A memproses permintaan itu menganggap ia sah

Kaedah Perlindungan CSRF dalam PHP

1. Perlindungan Berasaskan Token Menggunakan Input Tersembunyi

Ini adalah kaedah yang paling biasa. Begini cara untuk melaksanakannya:

// In your session initialization (e.g., at login)
session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// In your form
function generateFormWithCSRFToken() {
    return '<form method="POST" action="/submit">
        <input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">
        <!-- rest of your form fields -->
        <input type="submit" value="Submit">
    </form>';
}

// In your form processing
function validateCSRFToken() {
    if (!isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token']) ||
        !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        die('CSRF token validation failed');
    }
    return true;
}
Salin selepas log masuk
Salin selepas log masuk

2. Perlindungan CSRF Menggunakan Pengepala Tersuai

Kaedah ini menggunakan permintaan AJAX dengan pengepala tersuai:

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

// Validate the token
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $headers = getallheaders();
    if (!isset($headers['X-CSRF-Token']) || 
        !hash_equals($_SESSION['csrf_token'], $headers['X-CSRF-Token'])) {
        http_response_code(403);
        die('CSRF token validation failed');
    }
}

// JavaScript Frontend
const csrfToken = '<?php echo $_SESSION["csrf_token"]; ?>';

fetch('/api/endpoint', {
    method: 'POST',
    headers: {
        'X-CSRF-Token': csrfToken,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
});
Salin selepas log masuk
Salin selepas log masuk

3. Serah Berganda Corak Kuki

Kaedah ini melibatkan penghantaran token sebagai kuki dan sebagai parameter permintaan:

// Set both cookie and session token
session_start();
$token = bin2hex(random_bytes(32));
$_SESSION['csrf_token'] = $token;
setcookie('csrf_token', $token, [
    'httponly' => true,
    'secure' => true,
    'samesite' => 'Strict'
]);

// Validation function
function validateDoubleSubmitToken() {
    if (!isset($_COOKIE['csrf_token']) || 
        !isset($_POST['csrf_token']) || 
        !isset($_SESSION['csrf_token'])) {
        return false;
    }

    return hash_equals($_COOKIE['csrf_token'], $_POST['csrf_token']) && 
           hash_equals($_SESSION['csrf_token'], $_POST['csrf_token']);
}
Salin selepas log masuk

4. Atribut Kuki SameSite

Aplikasi moden juga boleh menggunakan atribut kuki SameSite sebagai lapisan perlindungan tambahan:

// Set cookie with SameSite attribute
session_start();
session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'domain' => $_SERVER['HTTP_HOST'],
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict'
]);
Salin selepas log masuk

Amalan Terbaik untuk Perlindungan CSRF

  1. Penjanaan Token
    • Gunakan penjana nombor rawak selamat secara kriptografi
    • Buat token cukup panjang (sekurang-kurangnya 32 bait)
    • Jana token baharu untuk setiap sesi
function generateSecureToken($length = 32) {
    return bin2hex(random_bytes($length));
}
Salin selepas log masuk
  1. Pengesahan Token
    • Gunakan fungsi perbandingan selamat masa
    • Sahkan kehadiran dan nilai token
    • Laksanakan pengendalian ralat yang betul
function validateToken($userToken, $storedToken) {
    if (empty($userToken) || empty($storedToken)) {
        return false;
    }
    return hash_equals($storedToken, $userToken);
}
Salin selepas log masuk
  1. Pelaksanaan Borang
    • Sertakan token dalam semua bentuk
    • Laksanakan suntikan token automatik
    • Kendalikan putaran token
class CSRFProtection {
    public static function getTokenField() {
        return sprintf(
            '<input type="hidden" name="csrf_token" value="%s">',
            htmlspecialchars($_SESSION['csrf_token'])
        );
    }
}
Salin selepas log masuk

Perlindungan Khusus Rangka Kerja

Banyak rangka kerja PHP menyediakan perlindungan CSRF terbina dalam:

Contoh Laravel

// In your session initialization (e.g., at login)
session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// In your form
function generateFormWithCSRFToken() {
    return '<form method="POST" action="/submit">
        <input type="hidden" name="csrf_token" value="' . $_SESSION['csrf_token'] . '">
        <!-- rest of your form fields -->
        <input type="submit" value="Submit">
    </form>';
}

// In your form processing
function validateCSRFToken() {
    if (!isset($_POST['csrf_token']) || !isset($_SESSION['csrf_token']) ||
        !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        die('CSRF token validation failed');
    }
    return true;
}
Salin selepas log masuk
Salin selepas log masuk

Contoh Symfony

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

// Validate the token
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $headers = getallheaders();
    if (!isset($headers['X-CSRF-Token']) || 
        !hash_equals($_SESSION['csrf_token'], $headers['X-CSRF-Token'])) {
        http_response_code(403);
        die('CSRF token validation failed');
    }
}

// JavaScript Frontend
const csrfToken = '<?php echo $_SESSION["csrf_token"]; ?>';

fetch('/api/endpoint', {
    method: 'POST',
    headers: {
        'X-CSRF-Token': csrfToken,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
});
Salin selepas log masuk
Salin selepas log masuk

Perangkap Biasa yang Perlu Dielakkan

  1. Jangan gunakan token yang boleh diramal
  2. Jangan simpan token dalam pembolehubah JavaScript yang boleh diakses secara global
  3. Jangan langkau perlindungan CSRF untuk permintaan AJAX
  4. Jangan bergantung semata-mata pada menyemak pengepala Perujuk
  5. Jangan gunakan token yang sama untuk berbilang borang

Perlindungan CSRF adalah penting untuk keselamatan aplikasi web. Walaupun terdapat pelbagai pendekatan untuk melaksanakan perlindungan CSRF, pendekatan berasaskan token menggunakan medan borang tersembunyi kekal sebagai kaedah yang paling banyak digunakan dan boleh dipercayai. Ingat untuk menggabungkan kaedah perlindungan yang berbeza untuk keselamatan yang dipertingkatkan dan sentiasa ikuti amalan terbaik keselamatan apabila melaksanakan perlindungan CSRF dalam aplikasi PHP anda.

Ingat bahawa perlindungan CSRF harus menjadi sebahagian daripada strategi keselamatan yang lebih luas yang merangkumi pengurusan sesi yang betul, pengendalian kuki selamat dan pengesahan input.

Atas ialah kandungan terperinci Perlindungan CSRF dalam PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan