当前位置: 首页 > 面试题库 >

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

宣原
2023-03-14
问题内容

我正在尝试为我的网站上的表单添加一些安全性。一种形式是使用AJAX,另一种形式是简单的“与我们联系”形式。我正在尝试添加CSRF令牌。我遇到的问题是令牌有时仅在HTML“值”中显示。其余时间,该值为空。这是我在AJAX表单上使用的代码:

PHP:

if (!isset($_SESSION)) {
    session_start();
$_SESSION['formStarted'] = true;
}
if (!isset($_SESSION['token']))
{$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;

}

的HTML

 <form>
//...
<input type="hidden" name="token" value="<?php echo $token; ?>" />
//...
</form>

有什么建议么?


问题答案:

对于安全代码,请不要以这种方式生成令牌: $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密钥,然后使用类似以下的逻辑来呈现它:

<input type="hidden" name="token" value="<?php
    echo hash_hmac('sha256', '/my_form.php', $_SESSION['second_token']);
?>" />

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

$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函数,您可以使用两个通用令牌,如下所示:

<input type="hidden" name="token" value="{{ form_token() }}" />

或锁定的变体:

<input type="hidden" name="token" value="{{ form_token('/my_form.php') }}" />

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

一次性CSRF令牌

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

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



 类似资料:
  • CSRF攻击迫使经过身份验证的用户(受害者)发送伪造的HTTP请求,包括受害者的会话cookie到易受攻击的Web应用程序,这允许攻击者强制受害者的浏览器生成请求,以便易受攻击的应用程序感知来自受害者。 我们下面来了解这个漏洞的威胁代理,攻击向量,安全弱点,技术影响和业务影响。 威胁代理 - 任何人都可以将内容加载到用户的浏览器中,从而迫使他们向您的网站提交请求。 攻击者的方法 - 攻击者创建伪造

  • 问题内容: 我想为基于Struts 1.x框架的Web应用程序实施跨站点请求伪造预防。我知道struts 2框架为此提供了令牌拦截器,并且可以使用过滤器实现类似的功能。 我对一些想法感到困惑1)如何以简单的方式生成唯一令牌?(我可以为此目的使用Action类令牌来避免重复提交表单) 将struts 1.x框架令牌机制用于CSRF预防是否存在任何问题 问题答案: Struts 1 Action令牌方

  • 综述 CSRF 是一种强制最终用户在web应用认证的情况下执行操作的攻击。通过一些社会工程学技巧的帮助(比如通过电子邮件或聊天工具发送链接),攻击者能够让用户执行攻击者想要的操作。当面向普通用户时,一次成功的CSRF利用可以获取用户的数据。如果面向的用户时管理员账户的话,CSRF攻击能够攻破整个web应用系统。 CSRF依赖于下面条件: Web浏览器支持会话相关的功能(如cookies和http认

  • CSRF Middleware(跨站请求伪造) CSRF(Cross-site request forgery 跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。 跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对

  • 跨站请求伪造(CSRF)是一种漏洞利用,攻击者致使受害的最终用户按恶意URI(例如以误导的链接、图片或重定向提供给用户代理)到达受信任的服务器(通常由存在有效的会话Cookie而建立)。 针对客户端的重定向URI的CSRF攻击允许攻击者注入自己的授权码或访问令牌,这将导致在客户端中使用与攻击者的受保护资源关联的访问令牌而非受害者的(例如,保存受害者的银行账户信息到攻击者控制的受保护资源)。 客户端

  • 跨站请求伪造(Cross-site request forgery), 简称为 XSRF,是 Web 应用中常见的一个安全问题。前面的链接也详细讲述了 XSRF 攻击的实现方式。 当前防范 XSRF 的一种通用的方法,是对每一个用户都记录一个无法预知的 cookie 数据,然后要求所有提交的请求(POST/PUT/DELETE)中都必须带有这个 cookie 数据。如果此数据不匹配 ,那么这个请求