php如何跨站post,如何使用PHP正确添加跨站点请求伪造(CSRF)令牌

小编典典

对于安全代码,请不要以这种方式生成令牌: $token = md5(uniqid(rand(), TRUE));

rand() 是可以预见的

uniqid() 最多只加29位熵

md5() 不添加熵,而是确定性地将其混合

试试看:

生成CSRF令牌

PHP 7

session_start();

if (empty($_SESSION['token'])) {

$_SESSION['token'] = bin2hex(random_bytes(32));

}

$token = $_SESSION['token'];

旁注:我老板的一个开源项目是一项向后移植random_bytes()并移植random_int()到PHP

5项目中的计划。它是MIT许可的软件,可在Github和Composer上以paragonie /random_compat的形式获得。

PHP 5.3+(或ext-mcrypt)

session_start();

if (empty($_SESSION['token'])) {

if (function_exists('mcrypt_create_iv')) {

$_SESSION['token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));

} else {

$_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));

}

}

$token = $_SESSION['token'];

验证CSRF令牌

不要只是使用==甚至===使用hash_equals()(仅适用于PHP5.6+,但适用于具有hash-compat库的早期版本)。

if (!empty($_POST['token'])) {

if (hash_equals($_SESSION['token'], $_POST['token'])) {

// Proceed to process the form data

} else {

// Log this as a warning and keep an eye on these attempts

}

}

通过表单令牌进一步发展

您可以使用进一步限制令牌仅可用于特定形式hash_hmac()。HMAC是一种特殊的键控哈希函数,即使具有较弱的哈希函数(例如MD5),也可以安全使用。但是,我建议改为使用SHA-2系列哈希函数。

首先,生成第二个令牌用作HMAC密钥,然后使用类似以下的逻辑来呈现它:

然后在验证令牌时使用全等运算:

$calc = hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);

if (hash_equals($calc, $_POST['token'])) {

// Continue...

}

在不知道的情况下,无法为另一种形式重用为一种形式生成的令牌$_SESSION['second_token']。

重要的是,您要使用一个单独的令牌作为HMAC密钥,而不是您刚刚在页面上丢弃的令牌。

奖励:混合方法+ Twig集成

使用Twig模板引擎的任何人都可以通过在其Twig环境中添加以下过滤器来从简化的双重策略中受益:

$twigEnv->addFunction(

new \Twig_SimpleFunction(

'form_token',

function($lock_to = null) {

if (empty($_SESSION['token'])) {

$_SESSION['token'] = bin2hex(random_bytes(32));

}

if (empty($_SESSION['token2'])) {

$_SESSION['token2'] = random_bytes(32);

}

if (empty($lock_to)) {

return $_SESSION['token'];

}

return hash_hmac('sha256', $lock_to, $_SESSION['token2']);

}

)

);

使用此Twig函数,您可以使用两个通用令牌,如下所示:

或锁定的变体:

Twig只关心模板渲染。您仍然必须正确验证令牌。我认为,Twig战略提供了更大的灵活性和简便性,同时又保持了最大安全性的可能性。

一次性CSRF令牌

如果您有一个安全要求,即每个CSRF令牌只能使用一次,则最简单的策略是在每次成功验证后重新生成它。但是,这样做会使之前的所有令牌失效,而这与一次浏览多个选项卡的人不能很好地融合在一起。

Paragon Initiative Enterprises为这些极端情况维护了一个反CSRF库。它仅与一次性使用的形式令牌一起使用。当会话数据中存储了足够的令牌(默认配置:65535)时,它将首先循环出最旧的未兑换令牌。

2020-05-26

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值