CSRF (Cross-Site Request Forgery) — это атака, когда злоумышленник заставляет браузер пользователя выполнять нежелательные запросы к веб-приложению. CSRF-токен — это уникальный секретный ключ, который защищает от таких атак.
// Создаем токен если его нет
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
<form action="/process" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<!-- другие поля формы -->
<button type="submit">Отправить</button>
</form>
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
http_response_code(403);
die('Неверный CSRF-токен');
}
// Обработка формы
}
class CsrfGuard {
public static function generateToken(): string {
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
public static function validateToken(string $token): bool {
return isset($_SESSION['csrf_token']) &&
hash_equals($_SESSION['csrf_token'], $token);
}
public static function getTokenField(): string {
return '<input type="hidden" name="csrf_token" value="' . self::generateToken() . '">';
}
}
function csrfMiddleware($request, $response, $next) {
if ($request->isPost()) {
if (!CsrfGuard::validateToken($request->get('csrf_token'))) {
return $response->withStatus(403);
}
}
return $next($request, $response);
}
random_bytes()
)hash_equals()
вместо ==
)// В шаблоне
<meta name="csrf-token" content="<?= $_SESSION['csrf_token'] ?>">
// В JavaScript
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
if ($_SERVER['HTTP_X_CSRF_TOKEN'] !== $_SESSION['csrf_token']) {
http_response_code(403);
die('Invalid CSRF token');
}
SameSite cookies:
session_set_cookie_params([
'samesite' => 'Strict',
'secure' => true,
'httponly' => true
]);
Проверка Origin/Referer заголовков (дополнительная защита):
$allowedOrigins = ['https://yourdomain.com'];
if (!in_array($_SERVER['HTTP_ORIGIN'], $allowedOrigins)) {
die('Invalid request origin');
}
CSRF-токен — это обязательная мера безопасности для любого веб-приложения. Реализуйте его с помощью генерации уникального токена на сессию, встраивания в формы и строгой проверки на сервере. Для максимальной защиты комбинируйте CSRF-токены с SameSite cookies и проверкой Origin заголовков.