PHP 中的 CSRF 保护(保护.PHP.CSRF...)

wufei123 2025-01-05 阅读:72 评论:0
什么是 csrf? 跨站请求伪造 (csrf) 是一种网络安全漏洞,攻击者可以利用该漏洞诱骗经过身份验证的用户在他们当前登录的网站上执行不需要的操作。该攻击通过利用网站所拥有的信任来进行在用户的浏览器中。...

php 中的 csrf 保护

什么是 csrf?

跨站请求伪造 (csrf) 是一种网络安全漏洞,攻击者可以利用该漏洞诱骗经过身份验证的用户在他们当前登录的网站上执行不需要的操作。该攻击通过利用网站所拥有的信任来进行在用户的浏览器中。

csrf 攻击如何运作
  1. 用户登录合法网站 a 并收到会话 cookie
  2. 用户在仍登录 a 的情况下访问恶意网站 b
  3. 网站 b 包含向网站 a 发出请求的代码
  4. 浏览器自动包含会话 cookie
  5. 网站 a 处理请求,认为其合法
php中的csrf保护方法 1. 使用隐藏输入的基于令牌的保护

这是最常用的方法。实现方法如下:

PHP
// 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;
}
2. 使用自定义标头进行 csrf 保护

此方法使用带有自定义标头的 ajax 请求:

PHP
// 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)
});
3.双重提交cookie模式

此方法涉及将令牌作为 cookie 和请求参数发送:

PHP
// 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']);
}
4. samesite cookie 属性

现代应用程序还可以使用 samesite cookie 属性作为附加保护层:

PHP
// set cookie with samesite attribute
session_start();
session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'domain' => $_server['http_host'],
    'secure' => true,
    'httponly' => true,
    'samesite' => 'strict'
]);
csrf 保护的最佳实践
  1. 代币生成
    • 使用加密安全的随机数生成器
    • 使令牌足够长(至少 32 字节)
    • 为每个会话生成新的代币
PHP
function generatesecuretoken($length = 32) {
    return bin2hex(random_bytes($length));
}
  1. 令牌验证
    • 使用时序安全的比较函数
    • 验证代币的存在和价值
    • 实施正确的错误处理
PHP
function validatetoken($usertoken, $storedtoken) {
    if (empty($usertoken) || empty($storedtoken)) {
        return false;
    }
    return hash_equals($storedtoken, $usertoken);
}
  1. 表单实施
    • 包含所有形式的代币
    • 实现自动令牌注入
    • 处理令牌轮换
PHP
class csrfprotection {
    public static function gettokenfield() {
        return sprintf(
            '<input type="hidden" name="csrf_token" value="%s">',
            htmlspecialchars($_session['csrf_token'])
        );
    }
}
特定于框架的保护

许多 php 框架提供内置的 csrf 保护:

laravel 示例
PHP
// in your form
@csrf

// manual token generation
{{ csrf_field() }}
交响乐示例
PHP
// In your form
{{ csrf_token('form_name') }}
要避免的常见陷阱
  1. 不要使用可预测的标记
  2. 不要将令牌存储在全局可访问的 javascript 变量中
  3. 不要跳过 ajax 请求的 csrf 保护
  4. 不要仅仅依赖于检查 referer 标头
  5. 不要在多个表单中使用相同的令牌

csrf 保护对于 web 应用程序安全至关重要。虽然实现 csrf 保护的方法有多种,但使用隐藏表单字段的基于令牌的方法仍然是使用最广泛、最可靠的方法。请记住结合不同的保护方法以增强安全性,并在 php 应用程序中实施 csrf 保护时始终遵循安全最佳实践。

请记住,csrf 保护应该是更广泛的安全策略的一部分,其中包括适当的会话管理、安全 cookie 处理和输入验证。

以上就是PHP 中的 CSRF 保护的详细内容,更多请关注知识资源分享宝库其它相关文章!

版权声明

本站内容来源于互联网搬运,
仅限用于小范围内传播学习,请在下载后24小时内删除,
如果有侵权内容、不妥之处,请第一时间联系我们删除。敬请谅解!
E-mail:dpw1001@163.com

分享:

扫一扫在手机阅读、分享本文

发表评论
热门文章
  • BioWare埃德蒙顿工作室面临关闭危机,龙腾世纪制作总监辞职引关注(龙腾.总监.辞职.危机.面临.....)

    BioWare埃德蒙顿工作室面临关闭危机,龙腾世纪制作总监辞职引关注(龙腾.总监.辞职.危机.面临.....)
    知名变性人制作总监corrine busche离职bioware,引发业界震荡!外媒“smash jt”独家报道称,《龙腾世纪:影幢守护者》制作总监corrine busche已离开bioware,此举不仅引发了关于个人职业发展方向的讨论,更因其可能预示着bioware埃德蒙顿工作室即将关闭而备受关注。本文将深入分析busche离职的原因及其对bioware及游戏行业的影响。 Busche的告别信:挑战与感激并存 据“Smash JT”获得的内部邮件显示,Busche离职原...
  • boss直聘怎么取消面试预约 boss直聘上面试爽约了会怎么样(面试.爽约.预约.取消.boss.....)

    boss直聘怎么取消面试预约 boss直聘上面试爽约了会怎么样(面试.爽约.预约.取消.boss.....)
    求职宝典:boss直聘面试技巧及取消预约方法 各位求职者注意啦!在Boss直聘上,随意取消面试预约会留下爽约记录,影响后续求职!本文将指导您如何避免爽约,以及如何取消已预约的面试。 如何取消Boss直聘面试预约? 打开Boss直聘APP,进入“我的”页面。 点击“待面试”,查看面试日程。 选择需要取消的面试,点击“取消面试”按钮即可。 Boss直聘面试爽约的后果? 爽约行为会在HR端留下记录,影响您的求职成功率。其他HR也能看到您的不良记录,所以务必重视面试预约。...
  • 闪耀暖暖靡城永恒怎么样-闪耀暖暖靡城永恒套装介绍(闪耀.暖暖.套装.介绍.....)

    闪耀暖暖靡城永恒怎么样-闪耀暖暖靡城永恒套装介绍(闪耀.暖暖.套装.介绍.....)
    闪耀暖暖钻石竞技场第十七赛季“华梦泡影”即将开启!全新闪耀性感套装【靡城永恒】震撼来袭!想知道如何获得这套精美套装吗?快来看看吧! 【靡城永恒】套装设计理念抢先看: 设计灵感源于夜色中的孤星,象征着淡然、漠视一切的灰色瞳眸。设计师希望通过这套服装,展现出在虚幻与真实交织的夜幕下,一种独特的魅力。 服装细节考究,从面料的光泽、鞋跟声响到裙摆的弧度,都力求完美还原设计初衷。 【靡城永恒】套装设计亮点: 闪耀的绸缎与金丝交织,轻盈的羽毛增添华贵感。 这套服装仿佛是从无尽的黑...
  • 蛋仔派对2025最新皮肤兑换码汇总 最新皮肤兑换码一览(兑换.皮肤.最新.派对.汇总.....)

    蛋仔派对2025最新皮肤兑换码汇总 最新皮肤兑换码一览(兑换.皮肤.最新.派对.汇总.....)
    蛋仔派对2025最新皮肤兑换码大放送!游戏内新增多款皮肤兑换码,包含最新、福利和通用三种类型,助你轻松获取精美奖励! 赶紧来看看如何兑换吧! 兑换码列表: 最新兑换码: ccewndj4k4k、cdkqdfm4fh、peetnmp4ef、cdxymk8f67 福利兑换码: cca863ywtfa、eggy2310am、eggy2311gz、eggyeggy9wz 通用兑换码: pec74dkcty、jsrqkrrjmh、cd3wt7wrph、ccepn7d8cjf...
  • python怎么调用其他文件函数

    python怎么调用其他文件函数
    在 python 中调用其他文件中的函数,有两种方式:1. 使用 import 语句导入模块,然后调用 [模块名].[函数名]();2. 使用 from ... import 语句从模块导入特定函数,然后调用 [函数名]()。 如何在 Python 中调用其他文件中的函数 在 Python 中,您可以通过以下两种方式调用其他文件中的函数: 1. 使用 import 语句 优点:简单且易于使用。 缺点:会将整个模块导入到当前作用域中,可能会导致命名空间混乱。 步骤:...