PHP 中的跨站请求伪造

Cross-Site Request Forgery in PHP | SecureFlag Security Knowledge Base

预防

PHP 不提供针对 CSRF 攻击的内置保护;开发人员必须通过检查会话令牌或使用许多经过良好测试的库和框架之一来手动实现它。

PHP

以下步骤展示了如何action.php?do=logout使用 Synchronizer Token Pattern 保护端点免受 CSRF 攻击。

  1. 成功验证后,会以安全方式生成随机令牌并存储为用户的会话变量。
<?php
$_SESSION["csrf_token"] = bin2hex(random_bytes(32));
?>
  1. 现在,对状态更改端点的任何请求都action.php?do=logout必须将令牌作为 HTTP 参数传递。以下代码段显示了如何编写<a href>标记以将令牌作为 GET 参数传递。
<a href="action.php?do=logout&csrf=<?php echo $_SESSION["csrf_token"]; ?>">
  1. 以下代码段显示了如何通过将令牌作为隐藏字段传递来保护表单。
<form>
   <input type="hidden" name="csrf" value="<?php echo $_SESSION["csrf_token"]; ?>">
</form>
  1. 该文件action.php现在必须在执行受保护的代码之前验证csrf与保存在用户会话中的令牌相匹配的参数。使用安全的哈希比较函数,例如 PHP hash_equals()
if (!empty($_REQUEST["csrf"]) && hash_equals($_REQUEST["csrf_token"], $_SESSION["csrf_token"])) {
   // The token is correct, execute the functionality.
}
else {
   die("Anti CSRF token is missing or wrong.");
}

OWASP CSRF 保护器

OWASP CSRF Protector 是一个独立的 php 库,用于 Web 应用程序中的 CSRF 缓解。按照项目页面上的说明进行安装。要使用它,只需包含库并调用init()函数。

<?php
include_once __DIR__ .'/vendor/owasp/csrf-protector-php/libs/csrf/csrfprotector.php';

// Initialise CSRFGuard library
csrfProtector::init();

Symfony 框架

Symfony 表单组件默认提供自动 CSRF 保护。其他类型的资源,如常规 HTML 表单或任何其他状态更改路由,必须通过手动生成和检查 CSRF 令牌来明确保护。

考虑使用常规 HTML 表单来删除资源。首先,使用csrf_token()Twig 函数在模板中生成一个 CSRF 令牌,并将其存储为隐藏的表单字段。

<form action="/delete" method="post">
    <input type="hidden" name="token" value="{{ csrf_token('action-delete') }}"/>
</form>

然后,在控制器动作中获取 CSRF 令牌的值,并使用isCsrfTokenValid()来检查其有效性。

public function delete(Request $request)
{
    $submittedToken = $request->request->get('token');

    if (!$this->isCsrfTokenValid('action-delete', $submittedToken)) {
      // The token is not correct, redirect to the index.
      return $this->redirectToRoute('index');     
    } 

    // The token is correct, execute the functionality.
}

参考

OWASP -跨站点请求伪造备忘单MITRE - CWE 352 OWASP - CSRF 保护器Symfony -如何实现 CSRF 保护

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值